From 4e112eca7750a4f530c986be55c178c43c16d3ea Mon Sep 17 00:00:00 2001 From: Elliott Baron Date: Sat, 26 Jun 2010 22:27:34 -0400 Subject: Update codan plugins to CDT 7.0. * org.eclipse.cdt.codan.checkers.ui: Updated. * org.eclipse.cdt.codan.checkers: Updated. * org.eclipse.cdt.codan.core: Updated. * org.eclipse.cdt.codan.ui: Updated. * org.eclipse.cdt.codan.core.cxx: Added. * org.eclipse.cdt.codan.extension/META-INF/MANIFEST.MF: Import org.eclipse.cdt.codan.core.cxx.model. * org.eclipse.cdt.codan.extension/src/org/eclipse/cdt/codan/extension/checkers/AbstractPropSimChecker.java: Superclass moved. --- org.eclipse.cdt.codan.core/.project | 6 + org.eclipse.cdt.codan.core/.settings/CVS/Entries | 5 +- org.eclipse.cdt.codan.core/.settings/CVS/Tag | 1 + .../.settings/org.eclipse.jdt.core.prefs | 80 +- .../.settings/org.eclipse.jdt.ui.prefs | 3 +- org.eclipse.cdt.codan.core/CVS/Entries | 10 +- org.eclipse.cdt.codan.core/CVS/Tag | 1 + org.eclipse.cdt.codan.core/META-INF/CVS/Entries | 3 +- org.eclipse.cdt.codan.core/META-INF/CVS/Tag | 1 + org.eclipse.cdt.codan.core/META-INF/MANIFEST.MF | 19 +- org.eclipse.cdt.codan.core/OSGI-INF/CVS/Entries | 1 + org.eclipse.cdt.codan.core/OSGI-INF/CVS/Repository | 1 + org.eclipse.cdt.codan.core/OSGI-INF/CVS/Root | 1 + org.eclipse.cdt.codan.core/OSGI-INF/CVS/Tag | 1 + .../OSGI-INF/l10n/CVS/Entries | 1 + .../OSGI-INF/l10n/CVS/Repository | 1 + org.eclipse.cdt.codan.core/OSGI-INF/l10n/CVS/Root | 1 + org.eclipse.cdt.codan.core/OSGI-INF/l10n/CVS/Tag | 1 + .../OSGI-INF/l10n/bundle.properties | 19 + org.eclipse.cdt.codan.core/about.html | 24 + org.eclipse.cdt.codan.core/build.properties | 15 +- org.eclipse.cdt.codan.core/plugin.xml | 30 +- org.eclipse.cdt.codan.core/schema/CVS/Entries | 3 +- org.eclipse.cdt.codan.core/schema/CVS/Tag | 1 + org.eclipse.cdt.codan.core/schema/checkers.exsd | 53 + org.eclipse.cdt.codan.core/src/CVS/Tag | 1 + org.eclipse.cdt.codan.core/src/org/CVS/Tag | 1 + org.eclipse.cdt.codan.core/src/org/eclipse/CVS/Tag | 1 + .../src/org/eclipse/cdt/CVS/Tag | 1 + .../src/org/eclipse/cdt/codan/CVS/Entries | 1 + .../src/org/eclipse/cdt/codan/CVS/Tag | 1 + .../src/org/eclipse/cdt/codan/core/CVS/Entries | 10 +- .../src/org/eclipse/cdt/codan/core/CVS/Tag | 1 + .../eclipse/cdt/codan/core/CodanApplication.java | 94 - .../eclipse/cdt/codan/core/CodanCorePlugin.java | 14 +- .../org/eclipse/cdt/codan/core/CodanRuntime.java | 76 +- .../src/org/eclipse/cdt/codan/core/Messages.java | 36 + .../cdt/codan/core/PreferenceConstants.java | 14 +- .../org/eclipse/cdt/codan/core/messages.properties | 19 + .../cdt/codan/core/model/AbstractChecker.java | 115 +- .../AbstractCheckerWithProblemPreferences.java | 223 ++ .../codan/core/model/AbstractIndexAstChecker.java | 103 - .../codan/core/model/AbstractProblemLocation.java | 104 + .../org/eclipse/cdt/codan/core/model/CVS/Entries | 35 +- .../src/org/eclipse/cdt/codan/core/model/CVS/Tag | 1 + .../cdt/codan/core/model/CodanSeverity.java | 27 +- .../eclipse/cdt/codan/core/model/ICAstChecker.java | 21 - .../org/eclipse/cdt/codan/core/model/IChecker.java | 37 +- .../codan/core/model/ICheckerWithPreferences.java | 35 + .../cdt/codan/core/model/ICheckersRegistry.java | 114 +- .../cdt/codan/core/model/ICodanAstReconciler.java | 22 - .../cdt/codan/core/model/ICodanBuilder.java | 15 +- .../org/eclipse/cdt/codan/core/model/IProblem.java | 64 +- .../cdt/codan/core/model/IProblemCategory.java | 33 +- .../cdt/codan/core/model/IProblemElement.java | 12 +- .../cdt/codan/core/model/IProblemLocation.java | 8 +- .../codan/core/model/IProblemLocationFactory.java | 67 + .../cdt/codan/core/model/IProblemProfile.java | 42 +- .../cdt/codan/core/model/IProblemReporter.java | 34 +- .../core/model/IProblemReporterPersistent.java | 45 + .../cdt/codan/core/model/IProblemWorkingCopy.java | 73 + .../codan/core/model/IRunnableInEditorChecker.java | 29 + .../cdt/codan/core/model/ProblemLocation.java | 109 - .../eclipse/cdt/codan/core/model/cfg/CVS/Entries | 13 + .../cdt/codan/core/model/cfg/CVS/Repository | 1 + .../org/eclipse/cdt/codan/core/model/cfg/CVS/Root | 1 + .../org/eclipse/cdt/codan/core/model/cfg/CVS/Tag | 1 + .../cdt/codan/core/model/cfg/IBasicBlock.java | 46 + .../cdt/codan/core/model/cfg/IBranchNode.java | 38 + .../eclipse/cdt/codan/core/model/cfg/ICfgData.java | 32 + .../cdt/codan/core/model/cfg/IConnectorNode.java | 25 + .../codan/core/model/cfg/IControlFlowGraph.java | 69 + .../cdt/codan/core/model/cfg/IDecisionNode.java | 29 + .../cdt/codan/core/model/cfg/IExitNode.java | 25 + .../cdt/codan/core/model/cfg/IJumpNode.java | 33 + .../cdt/codan/core/model/cfg/INodeFactory.java | 54 + .../cdt/codan/core/model/cfg/IPlainNode.java | 22 + .../cdt/codan/core/model/cfg/ISingleIncoming.java | 23 + .../cdt/codan/core/model/cfg/ISingleOutgoing.java | 23 + .../cdt/codan/core/model/cfg/IStartNode.java | 22 + .../core/param/AbstractProblemPreference.java | 202 ++ .../codan/core/param/BasicProblemPreference.java | 134 + .../org/eclipse/cdt/codan/core/param/CVS/Entries | 10 + .../eclipse/cdt/codan/core/param/CVS/Repository | 1 + .../src/org/eclipse/cdt/codan/core/param/CVS/Root | 1 + .../src/org/eclipse/cdt/codan/core/param/CVS/Tag | 1 + .../core/param/FileScopeProblemPreference.java | 267 ++ .../cdt/codan/core/param/IProblemPreference.java | 27 + .../IProblemPreferenceCompositeDescriptor.java | 51 + .../param/IProblemPreferenceCompositeValue.java | 42 + .../core/param/IProblemPreferenceDescriptor.java | 171 ++ .../codan/core/param/IProblemPreferenceValue.java | 54 + .../codan/core/param/ListProblemPreference.java | 323 +++ .../cdt/codan/core/param/MapProblemPreference.java | 261 ++ .../src/org/eclipse/cdt/codan/internal/CVS/Tag | 1 + .../eclipse/cdt/codan/internal/core/CVS/Entries | 11 +- .../org/eclipse/cdt/codan/internal/core/CVS/Tag | 1 + .../cdt/codan/internal/core/CharOperation.java | 2713 ++++++++++++++++++++ .../cdt/codan/internal/core/CheckersRegisry.java | 367 --- .../cdt/codan/internal/core/CheckersRegistry.java | 442 ++++ .../cdt/codan/internal/core/CodanApplication.java | 118 + .../cdt/codan/internal/core/CodanBuilder.java | 245 +- .../internal/core/CodanPreferencesLoader.java | 140 +- .../cdt/codan/internal/core/CodeAnlysisNature.java | 29 +- .../internal/core/cfg/AbstractBasicBlock.java | 61 + .../core/cfg/AbstractSingleIncomingNode.java | 56 + .../core/cfg/AbstractSingleOutgoingNode.java | 56 + .../cdt/codan/internal/core/cfg/BranchNode.java | 36 + .../cdt/codan/internal/core/cfg/CVS/Entries | 12 + .../cdt/codan/internal/core/cfg/CVS/Repository | 1 + .../eclipse/cdt/codan/internal/core/cfg/CVS/Root | 1 + .../eclipse/cdt/codan/internal/core/cfg/CVS/Tag | 1 + .../cdt/codan/internal/core/cfg/ConnectorNode.java | 69 + .../codan/internal/core/cfg/ControlFlowGraph.java | 147 ++ .../cdt/codan/internal/core/cfg/DecisionNode.java | 74 + .../cdt/codan/internal/core/cfg/ExitNode.java | 48 + .../cdt/codan/internal/core/cfg/JumpNode.java | 71 + .../cdt/codan/internal/core/cfg/NodeFactory.java | 101 + .../cdt/codan/internal/core/cfg/PlainNode.java | 54 + .../cdt/codan/internal/core/cfg/StartNode.java | 42 + .../cdt/codan/internal/core/model/CVS/Entries | 11 +- .../eclipse/cdt/codan/internal/core/model/CVS/Tag | 1 + .../core/model/CodanMarkerProblemReporter.java | 132 +- .../codan/internal/core/model/CodanProblem.java | 87 +- .../internal/core/model/CodanProblemCategory.java | 33 +- .../internal/core/model/CodanProblemLocation.java | 33 + .../core/model/ProblemLocationFactory.java | 53 + .../codan/internal/core/model/ProblemProfile.java | 18 +- 128 files changed, 7994 insertions(+), 1193 deletions(-) create mode 100644 org.eclipse.cdt.codan.core/.settings/CVS/Tag create mode 100644 org.eclipse.cdt.codan.core/CVS/Tag create mode 100644 org.eclipse.cdt.codan.core/META-INF/CVS/Tag create mode 100644 org.eclipse.cdt.codan.core/OSGI-INF/CVS/Entries create mode 100644 org.eclipse.cdt.codan.core/OSGI-INF/CVS/Repository create mode 100644 org.eclipse.cdt.codan.core/OSGI-INF/CVS/Root create mode 100644 org.eclipse.cdt.codan.core/OSGI-INF/CVS/Tag create mode 100644 org.eclipse.cdt.codan.core/OSGI-INF/l10n/CVS/Entries create mode 100644 org.eclipse.cdt.codan.core/OSGI-INF/l10n/CVS/Repository create mode 100644 org.eclipse.cdt.codan.core/OSGI-INF/l10n/CVS/Root create mode 100644 org.eclipse.cdt.codan.core/OSGI-INF/l10n/CVS/Tag create mode 100644 org.eclipse.cdt.codan.core/OSGI-INF/l10n/bundle.properties create mode 100644 org.eclipse.cdt.codan.core/about.html create mode 100644 org.eclipse.cdt.codan.core/schema/CVS/Tag create mode 100644 org.eclipse.cdt.codan.core/src/CVS/Tag create mode 100644 org.eclipse.cdt.codan.core/src/org/CVS/Tag create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/CVS/Tag create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/CVS/Tag create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/CVS/Tag create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/CVS/Tag delete mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/CodanApplication.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/Messages.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/messages.properties create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractCheckerWithProblemPreferences.java delete mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractIndexAstChecker.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractProblemLocation.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/CVS/Tag delete mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ICAstChecker.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ICheckerWithPreferences.java delete mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ICodanAstReconciler.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemLocationFactory.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemReporterPersistent.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemWorkingCopy.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IRunnableInEditorChecker.java delete mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ProblemLocation.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/CVS/Entries create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/CVS/Repository create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/CVS/Root create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/CVS/Tag create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IBasicBlock.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IBranchNode.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/ICfgData.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IConnectorNode.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IControlFlowGraph.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IDecisionNode.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IExitNode.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IJumpNode.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/INodeFactory.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IPlainNode.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/ISingleIncoming.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/ISingleOutgoing.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IStartNode.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/AbstractProblemPreference.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/BasicProblemPreference.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/CVS/Entries create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/CVS/Repository create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/CVS/Root create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/CVS/Tag create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/FileScopeProblemPreference.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/IProblemPreference.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/IProblemPreferenceCompositeDescriptor.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/IProblemPreferenceCompositeValue.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/IProblemPreferenceDescriptor.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/IProblemPreferenceValue.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/ListProblemPreference.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/MapProblemPreference.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/CVS/Tag create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CVS/Tag create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CharOperation.java delete mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CheckersRegisry.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CheckersRegistry.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanApplication.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/AbstractBasicBlock.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/AbstractSingleIncomingNode.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/AbstractSingleOutgoingNode.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/BranchNode.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/CVS/Entries create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/CVS/Repository create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/CVS/Root create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/CVS/Tag create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/ConnectorNode.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/ControlFlowGraph.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/DecisionNode.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/ExitNode.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/JumpNode.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/NodeFactory.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/PlainNode.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/StartNode.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CVS/Tag create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CodanProblemLocation.java create mode 100644 org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/ProblemLocationFactory.java (limited to 'org.eclipse.cdt.codan.core') diff --git a/org.eclipse.cdt.codan.core/.project b/org.eclipse.cdt.codan.core/.project index 8ba33e6..4edd707 100644 --- a/org.eclipse.cdt.codan.core/.project +++ b/org.eclipse.cdt.codan.core/.project @@ -20,9 +20,15 @@ + + org.eclipse.pde.api.tools.apiAnalysisBuilder + + + org.eclipse.pde.PluginNature org.eclipse.jdt.core.javanature + org.eclipse.pde.api.tools.apiAnalysisNature diff --git a/org.eclipse.cdt.codan.core/.settings/CVS/Entries b/org.eclipse.cdt.codan.core/.settings/CVS/Entries index eb6c3d6..28056e4 100644 --- a/org.eclipse.cdt.codan.core/.settings/CVS/Entries +++ b/org.eclipse.cdt.codan.core/.settings/CVS/Entries @@ -1,3 +1,2 @@ -/org.eclipse.jdt.core.prefs/1.3/Mon Aug 10 18:31:46 2009// -/org.eclipse.jdt.ui.prefs/1.1/Fri Nov 20 19:03:54 2009// -D +/org.eclipse.jdt.core.prefs/1.5/Sun Jun 27 01:30:41 2010//TCDT_7_0_0 +/org.eclipse.jdt.ui.prefs/1.2/Sun Jun 27 01:30:41 2010//TCDT_7_0_0 diff --git a/org.eclipse.cdt.codan.core/.settings/CVS/Tag b/org.eclipse.cdt.codan.core/.settings/CVS/Tag new file mode 100644 index 0000000..49a449a --- /dev/null +++ b/org.eclipse.cdt.codan.core/.settings/CVS/Tag @@ -0,0 +1 @@ +NCDT_7_0_0 diff --git a/org.eclipse.cdt.codan.core/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.cdt.codan.core/.settings/org.eclipse.jdt.core.prefs index 4452aee..dc332d1 100644 --- a/org.eclipse.cdt.codan.core/.settings/org.eclipse.jdt.core.prefs +++ b/org.eclipse.cdt.codan.core/.settings/org.eclipse.jdt.core.prefs @@ -1,4 +1,4 @@ -#Mon Aug 10 14:23:53 EDT 2009 +#Sun May 30 20:25:13 EDT 2010 eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 @@ -7,6 +7,84 @@ org.eclipse.jdt.core.compiler.compliance=1.5 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.doc.comment.support=enabled +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.comparingIdentical=error +org.eclipse.jdt.core.compiler.problem.deadCode=warning +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=warning org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning +org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled +org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=disabled +org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled +org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=public +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning +org.eclipse.jdt.core.compiler.problem.missingJavadocComments=warning +org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled +org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public +org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag +org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning +org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled +org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=public +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=warning +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=error +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning +org.eclipse.jdt.core.compiler.problem.nullReference=error +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=error +org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=error +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameter=warning +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning org.eclipse.jdt.core.compiler.source=1.5 diff --git a/org.eclipse.cdt.codan.core/.settings/org.eclipse.jdt.ui.prefs b/org.eclipse.cdt.codan.core/.settings/org.eclipse.jdt.ui.prefs index 2117213..17cb00c 100644 --- a/org.eclipse.cdt.codan.core/.settings/org.eclipse.jdt.ui.prefs +++ b/org.eclipse.cdt.codan.core/.settings/org.eclipse.jdt.ui.prefs @@ -1,4 +1,4 @@ -#Fri Nov 20 13:57:56 EST 2009 +#Sat May 15 15:20:42 EDT 2010 eclipse.preferences.version=1 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true sp_cleanup.add_default_serial_version_id=true @@ -8,6 +8,7 @@ sp_cleanup.add_missing_deprecated_annotations=true sp_cleanup.add_missing_methods=false sp_cleanup.add_missing_nls_tags=false sp_cleanup.add_missing_override_annotations=true +sp_cleanup.add_missing_override_annotations_interface_methods=false sp_cleanup.add_serial_version_id=false sp_cleanup.always_use_blocks=true sp_cleanup.always_use_parentheses_in_expressions=false diff --git a/org.eclipse.cdt.codan.core/CVS/Entries b/org.eclipse.cdt.codan.core/CVS/Entries index cb575f0..1e387b9 100644 --- a/org.eclipse.cdt.codan.core/CVS/Entries +++ b/org.eclipse.cdt.codan.core/CVS/Entries @@ -1,8 +1,10 @@ -/.classpath/1.3/Wed Dec 16 21:48:48 2009// -/.project/1.1/Thu Apr 9 12:46:50 2009// +/.classpath/1.3/Wed Dec 16 21:48:48 2009//TCDT_7_0_0 +/.project/1.2/Wed Mar 24 03:32:02 2010//TCDT_7_0_0 D/.settings//// D/META-INF//// -/build.properties/1.1/Thu Apr 9 12:46:50 2009// -/plugin.xml/1.5/Sat Aug 22 21:16:49 2009// +D/OSGI-INF//// +/about.html/1.1/Mon Jun 14 18:35:19 2010//TCDT_7_0_0 +/build.properties/1.6/Sun Jun 27 01:30:40 2010//TCDT_7_0_0 +/plugin.xml/1.11/Sun Jun 27 01:30:40 2010//TCDT_7_0_0 D/schema//// D/src//// diff --git a/org.eclipse.cdt.codan.core/CVS/Tag b/org.eclipse.cdt.codan.core/CVS/Tag new file mode 100644 index 0000000..49a449a --- /dev/null +++ b/org.eclipse.cdt.codan.core/CVS/Tag @@ -0,0 +1 @@ +NCDT_7_0_0 diff --git a/org.eclipse.cdt.codan.core/META-INF/CVS/Entries b/org.eclipse.cdt.codan.core/META-INF/CVS/Entries index 222d593..f617c99 100644 --- a/org.eclipse.cdt.codan.core/META-INF/CVS/Entries +++ b/org.eclipse.cdt.codan.core/META-INF/CVS/Entries @@ -1,2 +1 @@ -/MANIFEST.MF/1.5/Wed Dec 16 21:48:48 2009// -D +/MANIFEST.MF/1.16/Sun Jun 27 01:30:41 2010//TCDT_7_0_0 diff --git a/org.eclipse.cdt.codan.core/META-INF/CVS/Tag b/org.eclipse.cdt.codan.core/META-INF/CVS/Tag new file mode 100644 index 0000000..49a449a --- /dev/null +++ b/org.eclipse.cdt.codan.core/META-INF/CVS/Tag @@ -0,0 +1 @@ +NCDT_7_0_0 diff --git a/org.eclipse.cdt.codan.core/META-INF/MANIFEST.MF b/org.eclipse.cdt.codan.core/META-INF/MANIFEST.MF index b6eba46..33aacc3 100644 --- a/org.eclipse.cdt.codan.core/META-INF/MANIFEST.MF +++ b/org.eclipse.cdt.codan.core/META-INF/MANIFEST.MF @@ -1,15 +1,22 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 -Bundle-Name: Code Analysis Core +Bundle-Name: %Bundle-Name Bundle-SymbolicName: org.eclipse.cdt.codan.core;singleton:=true -Bundle-Version: 1.0.0 +Bundle-Version: 1.0.0.qualifier Bundle-Activator: org.eclipse.cdt.codan.core.CodanCorePlugin -Bundle-Vendor: CDT +Bundle-Vendor: %Bundle-Vendor Require-Bundle: org.eclipse.core.runtime, - org.eclipse.core.resources, - org.eclipse.cdt.core + org.eclipse.core.resources Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: J2SE-1.5 Export-Package: org.eclipse.cdt.codan.core, org.eclipse.cdt.codan.core.model, - org.eclipse.cdt.codan.internal.core;x-friends:="org.eclipse.cdt.codan.core,org.eclipse.cdt.codan.core.test,org.eclipse.cdt.codan.ui" + org.eclipse.cdt.codan.core.model.cfg;x-friends:="org.eclipse.cdt.codan.core.cxx,org.eclipse.cdt.codan.checkers", + org.eclipse.cdt.codan.core.param, + org.eclipse.cdt.codan.internal.core; + x-friends:="org.eclipse.cdt.codan.core, + org.eclipse.cdt.codan.core.cxx, + org.eclipse.cdt.codan.core.test, + org.eclipse.cdt.codan.ui", + org.eclipse.cdt.codan.internal.core.cfg;x-friends:="org.eclipse.cdt.codan.core.cxx", + org.eclipse.cdt.codan.internal.core.model;x-friends:="org.eclipse.cdt.codan.core.cxx,org.eclipse.cdt.codan.core.test,org.eclipse.cdt.codan.ui" diff --git a/org.eclipse.cdt.codan.core/OSGI-INF/CVS/Entries b/org.eclipse.cdt.codan.core/OSGI-INF/CVS/Entries new file mode 100644 index 0000000..2928641 --- /dev/null +++ b/org.eclipse.cdt.codan.core/OSGI-INF/CVS/Entries @@ -0,0 +1 @@ +D/l10n//// diff --git a/org.eclipse.cdt.codan.core/OSGI-INF/CVS/Repository b/org.eclipse.cdt.codan.core/OSGI-INF/CVS/Repository new file mode 100644 index 0000000..897fbf9 --- /dev/null +++ b/org.eclipse.cdt.codan.core/OSGI-INF/CVS/Repository @@ -0,0 +1 @@ +org.eclipse.cdt/codan/org.eclipse.cdt.codan.core/OSGI-INF diff --git a/org.eclipse.cdt.codan.core/OSGI-INF/CVS/Root b/org.eclipse.cdt.codan.core/OSGI-INF/CVS/Root new file mode 100644 index 0000000..04efa23 --- /dev/null +++ b/org.eclipse.cdt.codan.core/OSGI-INF/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@dev.eclipse.org:/cvsroot/tools diff --git a/org.eclipse.cdt.codan.core/OSGI-INF/CVS/Tag b/org.eclipse.cdt.codan.core/OSGI-INF/CVS/Tag new file mode 100644 index 0000000..3cd1ca4 --- /dev/null +++ b/org.eclipse.cdt.codan.core/OSGI-INF/CVS/Tag @@ -0,0 +1 @@ +TCDT_7_0_0 diff --git a/org.eclipse.cdt.codan.core/OSGI-INF/l10n/CVS/Entries b/org.eclipse.cdt.codan.core/OSGI-INF/l10n/CVS/Entries new file mode 100644 index 0000000..3c7dd91 --- /dev/null +++ b/org.eclipse.cdt.codan.core/OSGI-INF/l10n/CVS/Entries @@ -0,0 +1 @@ +/bundle.properties/1.2/Thu Jun 3 17:01:53 2010//TCDT_7_0_0 diff --git a/org.eclipse.cdt.codan.core/OSGI-INF/l10n/CVS/Repository b/org.eclipse.cdt.codan.core/OSGI-INF/l10n/CVS/Repository new file mode 100644 index 0000000..dcc0604 --- /dev/null +++ b/org.eclipse.cdt.codan.core/OSGI-INF/l10n/CVS/Repository @@ -0,0 +1 @@ +org.eclipse.cdt/codan/org.eclipse.cdt.codan.core/OSGI-INF/l10n diff --git a/org.eclipse.cdt.codan.core/OSGI-INF/l10n/CVS/Root b/org.eclipse.cdt.codan.core/OSGI-INF/l10n/CVS/Root new file mode 100644 index 0000000..04efa23 --- /dev/null +++ b/org.eclipse.cdt.codan.core/OSGI-INF/l10n/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@dev.eclipse.org:/cvsroot/tools diff --git a/org.eclipse.cdt.codan.core/OSGI-INF/l10n/CVS/Tag b/org.eclipse.cdt.codan.core/OSGI-INF/l10n/CVS/Tag new file mode 100644 index 0000000..49a449a --- /dev/null +++ b/org.eclipse.cdt.codan.core/OSGI-INF/l10n/CVS/Tag @@ -0,0 +1 @@ +NCDT_7_0_0 diff --git a/org.eclipse.cdt.codan.core/OSGI-INF/l10n/bundle.properties b/org.eclipse.cdt.codan.core/OSGI-INF/l10n/bundle.properties new file mode 100644 index 0000000..88acd6e --- /dev/null +++ b/org.eclipse.cdt.codan.core/OSGI-INF/l10n/bundle.properties @@ -0,0 +1,19 @@ +############################################################################### +# Copyright (c) 2010 Alena Laskavaia and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Alena Laskavaia - initial API and implementation +############################################################################### +#Properties file for org.eclipse.cdt.codan.core +Bundle-Vendor = Eclipse CDT +Bundle-Name = Code Analysis Core +extension.name.Builder = Code Analysis Project Builder +extension.name.Nature = Code Analysis Nature +extension.name.Marker = Code Analysis Problem +category.name.ProgrammingErrors = Potential programming problems +category.name.CodeStyle = Coding Style +extension-point.name.CodeAnalysis = Code Analysis Checkers \ No newline at end of file diff --git a/org.eclipse.cdt.codan.core/about.html b/org.eclipse.cdt.codan.core/about.html new file mode 100644 index 0000000..d7c5118 --- /dev/null +++ b/org.eclipse.cdt.codan.core/about.html @@ -0,0 +1,24 @@ + + +About + + +

About This Content

+ +

June 22, 2007

+

License

+ +

The Eclipse Foundation 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 +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at http://www.eclipse.org/legal/epl-v10.html. +For purposes of the EPL, "Program" will mean the Content.

+ +

If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at http://www.eclipse.org.

+ + \ No newline at end of file diff --git a/org.eclipse.cdt.codan.core/build.properties b/org.eclipse.cdt.codan.core/build.properties index 3595411..b599b4a 100644 --- a/org.eclipse.cdt.codan.core/build.properties +++ b/org.eclipse.cdt.codan.core/build.properties @@ -1,6 +1,19 @@ +############################################################################### +# Copyright (c) 2009, 2010 Alena Laskavaia and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Alena Laskavaia - initial API and implementation +############################################################################### source.. = src/ output.. = bin/ bin.includes = META-INF/,\ .,\ plugin.xml,\ - schema/ + schema/,\ + OSGI-INF/l10n/bundle.properties,\ + about.html +src.includes = schema/ diff --git a/org.eclipse.cdt.codan.core/plugin.xml b/org.eclipse.cdt.codan.core/plugin.xml index b7b10a0..1b051a3 100644 --- a/org.eclipse.cdt.codan.core/plugin.xml +++ b/org.eclipse.cdt.codan.core/plugin.xml @@ -1,11 +1,11 @@ - + @@ -16,7 +16,7 @@ + + + + + type="org.eclipse.cdt.core.problem"> + + + + + @@ -48,9 +59,12 @@ + - @@ -62,7 +76,7 @@ thread="main" visible="true"> + class="org.eclipse.cdt.codan.internal.core.CodanApplication"> diff --git a/org.eclipse.cdt.codan.core/schema/CVS/Entries b/org.eclipse.cdt.codan.core/schema/CVS/Entries index 2905ba5..f6008c3 100644 --- a/org.eclipse.cdt.codan.core/schema/CVS/Entries +++ b/org.eclipse.cdt.codan.core/schema/CVS/Entries @@ -1,2 +1 @@ -/checkers.exsd/1.1/Thu Apr 9 12:46:50 2009// -D +/checkers.exsd/1.5/Sun Jun 27 01:30:41 2010//TCDT_7_0_0 diff --git a/org.eclipse.cdt.codan.core/schema/CVS/Tag b/org.eclipse.cdt.codan.core/schema/CVS/Tag new file mode 100644 index 0000000..49a449a --- /dev/null +++ b/org.eclipse.cdt.codan.core/schema/CVS/Tag @@ -0,0 +1 @@ +NCDT_7_0_0 diff --git a/org.eclipse.cdt.codan.core/schema/checkers.exsd b/org.eclipse.cdt.codan.core/schema/checkers.exsd index 71808a5..1990117 100644 --- a/org.eclipse.cdt.codan.core/schema/checkers.exsd +++ b/org.eclipse.cdt.codan.core/schema/checkers.exsd @@ -60,6 +60,7 @@ + @@ -143,6 +144,43 @@ + + + + If problem is enabled in original profile. Default is true. + + + + + + + Default error message pattern. Use java pattern notation such as {0} to replace with first argument, and so on. + + + + + + + + + + Short description of the problem + + + + + + + + + + Marker type to use to generate problem, default is the generic codan marker + + + + + + @@ -178,6 +216,21 @@ + + + + + + Reference to a problem + + + + + + + + + diff --git a/org.eclipse.cdt.codan.core/src/CVS/Tag b/org.eclipse.cdt.codan.core/src/CVS/Tag new file mode 100644 index 0000000..3cd1ca4 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/CVS/Tag @@ -0,0 +1 @@ +TCDT_7_0_0 diff --git a/org.eclipse.cdt.codan.core/src/org/CVS/Tag b/org.eclipse.cdt.codan.core/src/org/CVS/Tag new file mode 100644 index 0000000..3cd1ca4 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/CVS/Tag @@ -0,0 +1 @@ +TCDT_7_0_0 diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/CVS/Tag b/org.eclipse.cdt.codan.core/src/org/eclipse/CVS/Tag new file mode 100644 index 0000000..3cd1ca4 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/CVS/Tag @@ -0,0 +1 @@ +TCDT_7_0_0 diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/CVS/Tag b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/CVS/Tag new file mode 100644 index 0000000..3cd1ca4 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/CVS/Tag @@ -0,0 +1 @@ +TCDT_7_0_0 diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/CVS/Entries b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/CVS/Entries index 94f7274..d028aeb 100644 --- a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/CVS/Entries +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/CVS/Entries @@ -1,2 +1,3 @@ D/core//// D/internal//// +D/provisional//// diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/CVS/Tag b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/CVS/Tag new file mode 100644 index 0000000..3cd1ca4 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/CVS/Tag @@ -0,0 +1 @@ +TCDT_7_0_0 diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/CVS/Entries b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/CVS/Entries index d3c5192..3e108e0 100644 --- a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/CVS/Entries +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/CVS/Entries @@ -1,6 +1,8 @@ -/CodanApplication.java/1.2/Sat Aug 22 21:16:48 2009// -/CodanCorePlugin.java/1.3/Sat Aug 22 21:16:48 2009// -/CodanRuntime.java/1.1/Sat Aug 22 21:16:48 2009// -/PreferenceConstants.java/1.2/Sat Apr 18 04:01:43 2009// +/CodanCorePlugin.java/1.5/Sun Jun 27 01:30:41 2010//TCDT_7_0_0 +/CodanRuntime.java/1.6/Sun Jun 27 01:30:41 2010//TCDT_7_0_0 +/Messages.java/1.3/Tue May 25 01:33:23 2010//TCDT_7_0_0 +/PreferenceConstants.java/1.6/Sun Jun 27 01:30:41 2010//TCDT_7_0_0 D/builder//// +/messages.properties/1.4/Thu Jun 3 17:01:53 2010//TCDT_7_0_0 D/model//// +D/param//// diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/CVS/Tag b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/CVS/Tag new file mode 100644 index 0000000..49a449a --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/CVS/Tag @@ -0,0 +1 @@ +NCDT_7_0_0 diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/CodanApplication.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/CodanApplication.java deleted file mode 100644 index e0287b1..0000000 --- a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/CodanApplication.java +++ /dev/null @@ -1,94 +0,0 @@ -package org.eclipse.cdt.codan.core; - -import java.util.ArrayList; -import java.util.Collection; - -import org.eclipse.cdt.codan.internal.core.CodanBuilder; -import org.eclipse.cdt.codan.internal.core.model.CodanMarkerProblemReporter; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IWorkspaceRoot; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.equinox.app.IApplication; -import org.eclipse.equinox.app.IApplicationContext; - -public class CodanApplication implements IApplication { - private Collection projects = new ArrayList(); - private boolean verbose = false; - private boolean all = false; - - public Object start(IApplicationContext context) throws Exception { - String[] args = (String[]) context.getArguments().get( - "application.args"); - if (args == null || args.length == 0) { - help(); - return EXIT_OK; - } - extractArguments(args); - CodanBuilder codanBuilder = new CodanBuilder(); - CodanRuntime runtime = CodanRuntime.getInstance(); - runtime.setProblemReporter(new CodanMarkerProblemReporter() { - @Override - public void reportProblem(String id, int severity, IFile file, - int lineNumber, int startChar, int endChar, String message) { - System.out.println(file.getLocation() + ":" + lineNumber + ": " - + message); - } - }); - IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); - if (all) { - log("Launching analysis on workspace"); - root.accept(codanBuilder.new CodanResourceVisitor()); - } else { - for (String project : projects) { - log("Launching analysis on project " + project); - IProject wProject = root.getProject(project); - if (!wProject.exists()) { - System.err.println("Error: project " + project - + " does not exist"); - continue; - } - wProject.accept(codanBuilder.new CodanResourceVisitor()); - } - } - return EXIT_OK; - } - - /** - * @param string - */ - private void log(String string) { - if (verbose) - System.err.println(string); - } - - /** - * @param args - */ - private void extractArguments(String[] args) { - for (int i = 0; i < args.length; i++) { - String string = args[i]; - if (string.equals("-verbose")) { - verbose = true; - } else if (string.equals("-all")) { - all = true; - } else { - projects.add(string); - } - } - } - - /** - * - */ - private void help() { - System.out.println("Usage: [options] ..."); - System.out.println("Options:"); - System.out.println(" -all - run on all projects in workspace"); - System.out.println(" -verbose - print extra build information"); - } - - public void stop() { - // nothing - } -} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/CodanCorePlugin.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/CodanCorePlugin.java index d60262b..90e5d83 100644 --- a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/CodanCorePlugin.java +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/CodanCorePlugin.java @@ -1,3 +1,13 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Alena Laskavaia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ package org.eclipse.cdt.codan.core; import org.eclipse.cdt.codan.internal.core.CodeAnlysisNature; @@ -13,7 +23,7 @@ import org.osgi.framework.BundleContext; */ public class CodanCorePlugin extends Plugin { // The plug-in ID - public static final String PLUGIN_ID = "org.eclipse.cdt.codan.core"; + public static final String PLUGIN_ID = "org.eclipse.cdt.codan.core"; //$NON-NLS-1$ public static final String NATURE_ID = CodeAnlysisNature.NATURE_ID; // The shared instance private static CodanCorePlugin plugin; @@ -34,6 +44,7 @@ public class CodanCorePlugin extends Plugin { * @see * org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext) */ + @Override public void start(BundleContext context) throws Exception { super.start(context); plugin = this; @@ -45,6 +56,7 @@ public class CodanCorePlugin extends Plugin { * @see * org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext) */ + @Override public void stop(BundleContext context) throws Exception { plugin = null; super.stop(context); diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/CodanRuntime.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/CodanRuntime.java index 16375cf..bc7b3d7 100644 --- a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/CodanRuntime.java +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/CodanRuntime.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Alena Laskavaia + * Copyright (c) 2009, 2010 Alena Laskavaia * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -11,44 +11,102 @@ package org.eclipse.cdt.codan.core; import org.eclipse.cdt.codan.core.model.ICheckersRegistry; -import org.eclipse.cdt.codan.core.model.ICodanAstReconciler; import org.eclipse.cdt.codan.core.model.ICodanBuilder; +import org.eclipse.cdt.codan.core.model.IProblemLocationFactory; import org.eclipse.cdt.codan.core.model.IProblemReporter; -import org.eclipse.cdt.codan.internal.core.CheckersRegisry; +import org.eclipse.cdt.codan.internal.core.CheckersRegistry; import org.eclipse.cdt.codan.internal.core.CodanBuilder; import org.eclipse.cdt.codan.internal.core.model.CodanMarkerProblemReporter; +import org.eclipse.cdt.codan.internal.core.model.ProblemLocationFactory; /** * Runtime singleton class to get access to Codan framework parts * + * Clients may extend this class to override default framework parts. + * + *

+ * EXPERIMENTAL. This class or interface has been added as part + * of a work in progress. There is no guarantee that this API will work or that + * it will remain the same. + *

*/ public class CodanRuntime { private static CodanRuntime instance = new CodanRuntime(); private IProblemReporter problemReporter = new CodanMarkerProblemReporter(); - private CodanBuilder builder = new CodanBuilder(); - private CheckersRegisry checkers = CheckersRegisry.getInstance(); + private ICodanBuilder builder = new CodanBuilder(); + private CheckersRegistry checkers = CheckersRegistry.getInstance(); + private IProblemLocationFactory locFactory = new ProblemLocationFactory(); + + /** + * CodanRuntime - only can be called by subclasses to override default + * constructor + */ + protected CodanRuntime() { + // nothing here + } + /** + * Get runtime problem reporter. Default reported generated problem markers. + * + * @return + */ public IProblemReporter getProblemReporter() { return problemReporter; } + /** + * Set different problem reporter. + * + * @param reporter + */ public void setProblemReporter(IProblemReporter reporter) { problemReporter = reporter; } + /** + * Get instance of of Codan Runtime + * + * @return + */ public static CodanRuntime getInstance() { return instance; } + /** + * Get builder. Builder can used to run code analysis on given resource + * using API. + * + * @return + */ public ICodanBuilder getBuilder() { return builder; } - public ICodanAstReconciler getAstQuickBuilder() { - return builder; - } - + /** + * Get checkers registry. + * + * @return + */ public ICheckersRegistry getChechersRegistry() { return checkers; } + + /** + * Get problem location factory. + * + * @return + */ + public IProblemLocationFactory getProblemLocationFactory() { + return locFactory; + } + + /** + * Set another problem location factory - only need if default is not + * sufficient, i.e IProblemLocation is implemented differently + * + * @param factory + */ + public void setProblemLocationFactory(IProblemLocationFactory factory) { + locFactory = factory; + } } diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/Messages.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/Messages.java new file mode 100644 index 0000000..312c5c2 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/Messages.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2009,2010 Alena Laskavaia + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core; + +import org.eclipse.osgi.util.NLS; + +/** + * Core Messages + */ +public class Messages extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.cdt.codan.core.messages"; //$NON-NLS-1$ + public static String CodanApplication_all_option; + public static String CodanApplication_Error_ProjectDoesNotExists; + public static String CodanApplication_LogRunProject; + public static String CodanApplication_LogRunWorkspace; + public static String CodanApplication_Options; + public static String CodanApplication_Usage; + public static String CodanApplication_verbose_option; + public static String CodanBuilder_Code_Analysis_On; + public static String FileScopeProblemPreference_Label; + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/PreferenceConstants.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/PreferenceConstants.java index a4a1374..c730e9e 100644 --- a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/PreferenceConstants.java +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/PreferenceConstants.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Alena Laskavaia + * Copyright (c) 2009, 2010 Alena Laskavaia * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -12,9 +12,15 @@ package org.eclipse.cdt.codan.core; /** * Constant definitions for plug-in preferences + *

+ * EXPERIMENTAL. This class or interface has been added as part + * of a work in progress. There is no guarantee that this API will work or that + * it will remain the same. + *

*/ public class PreferenceConstants { - public static final String P_RUN_ON_BUILD = "booleanPreference"; - public static final String P_PROBLEMS = "problems"; - public static final String P_USE_PARENT = "useParentScope"; + public static final String P_RUN_ON_BUILD = "onBuild"; //$NON-NLS-1$ + public static final String P_RUN_IN_EDITOR = "inEditor"; //$NON-NLS-1$ + public static final String P_PROBLEMS = "problems"; //$NON-NLS-1$ + public static final String P_USE_PARENT = "useParentScope"; //$NON-NLS-1$ } diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/messages.properties b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/messages.properties new file mode 100644 index 0000000..d27aa29 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/messages.properties @@ -0,0 +1,19 @@ +############################################################################### +# Copyright (c) 2010 Alena Laskavaia and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Alena Laskavaia - initial API and implementation +############################################################################### +CodanApplication_Error_ProjectDoesNotExists=Error: project {0} does not exist +CodanApplication_LogRunProject=Running code analysis on project +CodanApplication_LogRunWorkspace=Running code analysis on workspace +CodanApplication_Usage=Usage: [options] ... +CodanApplication_Options=Options: +CodanApplication_all_option= -all - run on all projects in workspace +CodanApplication_verbose_option= -verbose - print verbose build information +CodanBuilder_Code_Analysis_On=Code analysis on +FileScopeProblemPreference_Label=Exclusion and Inclusion diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractChecker.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractChecker.java index f1e5028..411ba67 100644 --- a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractChecker.java +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractChecker.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Alena Laskavaia + * Copyright (c) 2009, 2010 Alena Laskavaia * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -11,12 +11,21 @@ package org.eclipse.cdt.codan.core.model; import org.eclipse.cdt.codan.core.CodanRuntime; +import org.eclipse.cdt.codan.internal.core.CheckersRegistry; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; +/** + * Convenience implementation of IChecker interface. Has a default + * implementation for common methods. + * + */ public abstract class AbstractChecker implements IChecker { protected String name; + /** + * Default constructor + */ public AbstractChecker() { } @@ -32,19 +41,38 @@ public abstract class AbstractChecker implements IChecker { * Reports a simple problem for given file and line * * @param id - * - problem id + * - problem id * @param file - * - file + * - file * @param lineNumber - * - line - * @param arg - * - problem argument, if problem does not define error message - * it will be error message (not recommended because of - * internationalization) + * - line + * @param args + * - problem arguments, if problem does not define error message + * it will be error message (not recommended because of + * internationalization) */ - public void reportProblem(String id, IFile file, int lineNumber, String arg) { + public void reportProblem(String id, IFile file, int lineNumber, + Object... args) { getProblemReporter().reportProblem(id, - new ProblemLocation(file, lineNumber), arg); + createProblemLocation(file, lineNumber), args); + } + + /** + * Finds an instance of problem by given id, in user profile registered for + * specific file + * + * @param id + * - problem id + * @param file + * - file in scope + * @return problem instance + */ + public IProblem getProblemById(String id, IResource file) { + IProblem problem = CheckersRegistry.getInstance() + .getResourceProfile(file).findProblem(id); + if (problem == null) + throw new IllegalArgumentException("Id is not registered"); //$NON-NLS-1$ + return problem; } /** @@ -52,15 +80,15 @@ public abstract class AbstractChecker implements IChecker { * from problem definition * * @param id - * - problem id + * - problem id * @param file - * - file + * - file * @param lineNumber - * - line + * - line */ public void reportProblem(String id, IFile file, int lineNumber) { getProblemReporter().reportProblem(id, - new ProblemLocation(file, lineNumber), new Object[] {}); + createProblemLocation(file, lineNumber), new Object[] {}); } /** @@ -70,7 +98,64 @@ public abstract class AbstractChecker implements IChecker { return CodanRuntime.getInstance().getProblemReporter(); } + /** + * Convenience method to return codan runtime + * + * @return + */ + protected CodanRuntime getRuntime() { + return CodanRuntime.getInstance(); + } + + /** + * Convenience method to create and return instance of IProblemLocation + * + * @param file + * - file where problem is found + * @param line + * - line number 1-relative + * @return instance of IProblemLocation + */ + protected IProblemLocation createProblemLocation(IFile file, int line) { + return getRuntime().getProblemLocationFactory().createProblemLocation( + file, line); + } + + /** + * Convenience method to create and return instance of IProblemLocation + * + * @param file + * - file where problem is found + * @param startChar + * - start char of the problem in the file, is zero-relative + * @param endChar + * - end char of the problem in the file, is zero-relative and + * exclusive. + * @return instance of IProblemLocation + */ + protected IProblemLocation createProblemLocation(IFile file, int startChar, + int endChar) { + return getRuntime().getProblemLocationFactory().createProblemLocation( + file, startChar, endChar); + } + + /** + * Defines if checker should be run as user type in C editor. Override this + * method is checker is too heavy for that (runs too long) + */ public boolean runInEditor() { - return false; + return this instanceof IRunnableInEditorChecker; + } + + /** + * report a problem + * + * @param problemId - id of a problem + * @param loc - problem location + * @param args - extra problem arguments + */ + public void reportProblem(String problemId, IProblemLocation loc, + Object... args) { + getProblemReporter().reportProblem(problemId, loc, args); } } diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractCheckerWithProblemPreferences.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractCheckerWithProblemPreferences.java new file mode 100644 index 0000000..b58156f --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractCheckerWithProblemPreferences.java @@ -0,0 +1,223 @@ +/******************************************************************************* + * Copyright (c) 2009,2010 Alena Laskavaia + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.model; + +import java.util.Collection; +import java.util.Iterator; + +import org.eclipse.cdt.codan.core.param.AbstractProblemPreference; +import org.eclipse.cdt.codan.core.param.BasicProblemPreference; +import org.eclipse.cdt.codan.core.param.FileScopeProblemPreference; +import org.eclipse.cdt.codan.core.param.IProblemPreference; +import org.eclipse.cdt.codan.core.param.IProblemPreferenceDescriptor.PreferenceType; +import org.eclipse.cdt.codan.core.param.ListProblemPreference; +import org.eclipse.cdt.codan.core.param.MapProblemPreference; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IPath; + +/** + * AbstarctChecker that has extra methods to simplify adding problem + * preferences. + * Checker can produce several problems, but preferences are per problem. + * Sharing preferences between problems is not supported now. + */ +public abstract class AbstractCheckerWithProblemPreferences extends + AbstractChecker implements ICheckerWithPreferences { + /** + * Checker that actually has parameter must override this + */ + public void initPreferences(IProblemWorkingCopy problem) { + // by default add file scope preference + addPreference(problem, new FileScopeProblemPreference(), null); + } + + /** + * Scope preference - special preference that all file checkers should have, + * it allows user to include/exclude files for this specific problem. + * + * @param problem - problem for which scope preference is need + * @return scope problem preference, null if not defined + */ + public FileScopeProblemPreference getScopePreference(IProblem problem) { + FileScopeProblemPreference scope = (FileScopeProblemPreference) getTopLevelPreferenceMap( + problem).getChildDescriptor(FileScopeProblemPreference.KEY); + return scope; + } + + /** + * User can scope out some resources for this checker. Checker can use this + * call to test if it should run on this resource at all or not. Test should + * be done within processResource method not in enabledInContext. + * This test uses user "scope" preference for the all problems that this + * checker can produce. + * + * @param res - resource to test on + * @return true if checker should report problems, fails otherwise. + */ + public boolean shouldProduceProblems(IResource res) { + Collection refProblems = getRuntime().getChechersRegistry() + .getRefProblems(this); + for (Iterator iterator = refProblems.iterator(); iterator + .hasNext();) { + IProblem checkerProblem = iterator.next(); + if (shouldProduceProblem( + getProblemById(checkerProblem.getId(), res), + res.getLocation())) + return true; + } + return false; + } + + /** + * User can scope out some resources for this checker. Checker can use this + * call to test if it should run on this resource at all or produce a + * specific problem on this resource. Test should + * be done within processResource method not in enabledInContext, or just + * before printing of a problem. + * This test uses user "scope" preference for the given problem. If scope is + * not defined preference it returns true. + * + * @param problem - problem to test for + * @param resource - resource to test on + * + * @return true if problem should be report for given resource, fails + * otherwise. + */ + public boolean shouldProduceProblem(IProblem problem, IPath resource) { + FileScopeProblemPreference scope = getScopePreference(problem); + if (scope == null) + return true; + return scope.isInScope(resource); + } + + @Override + public void reportProblem(String problemId, IProblemLocation loc, + Object... args) { + if (shouldProduceProblem(getProblemById(problemId, loc.getFile()), loc + .getFile().getLocation())) + super.reportProblem(problemId, loc, args); + } + + /** + * Add a parameter + * + * @param problem + * - problem that has parameter + * @param key + * - parameter key + * @param label + * - parameter label - user visible + * @param defaultValue + * - parameter default value + * @return - parameter info object + */ + public IProblemPreference addPreference(IProblemWorkingCopy problem, + String key, String label, Object defaultValue) { + MapProblemPreference map = getTopLevelPreferenceMap(problem); + BasicProblemPreference info = new BasicProblemPreference(key, label, + PreferenceType.typeOf(defaultValue)); + map.addChildDescriptor(info); + setDefaultPreferenceValue(problem, key, defaultValue); + return info; + } + + /** + * Add preference of type list of strings, list is empty by + * default + * + * @param problem + * - problem + * @param key + * - preference key + * @param label + * - preference label + * @param itemLabel + * @return preference instance of of the list, can be used to add default + * values or set different element type + * + */ + public ListProblemPreference addListPreference(IProblemWorkingCopy problem, + String key, String label, String itemLabel) { + MapProblemPreference map = getTopLevelPreferenceMap(problem); + ListProblemPreference list = new ListProblemPreference(key, label); + list.setChildDescriptor(new BasicProblemPreference( + ListProblemPreference.COMMON_DESCRIPTOR_KEY, itemLabel, + PreferenceType.TYPE_STRING)); + return (ListProblemPreference) map.addChildDescriptor(list); + } + + /** + * Add preference for the given problem with default value + * + * @param problem + * @param pref - preference + * @param defaultValue - default value of the preference + * @return added preference + */ + public IProblemPreference addPreference(IProblemWorkingCopy problem, + IProblemPreference pref, Object defaultValue) { + MapProblemPreference map = getTopLevelPreferenceMap(problem); + String key = pref.getKey(); + pref = map.addChildDescriptor(pref); + setDefaultPreferenceValue(problem, key, defaultValue); + return pref; + } + + /** + * Convenience method for setting default preference value for checker that + * uses "map" as top level problem preference. + * + * @param problem - problem for which to set default value for a prefence + * @param key - preference key + * @param defaultValue - value of preference to be set + */ + protected void setDefaultPreferenceValue(IProblemWorkingCopy problem, + String key, Object defaultValue) { + MapProblemPreference map = getTopLevelPreferenceMap(problem); + if (map.getChildValue(key) == null) + map.setChildValue(key, defaultValue); + } + + /** + * Return "map" problem preference for a give problem, if problem + * has preference different than a map, it will throw ClassCastException. + * If top level preference does not exist create a map preference with name + * "params" + * and return it. + * + * @param problem + * @return top level preference if it is a map + */ + protected MapProblemPreference getTopLevelPreferenceMap(IProblem problem) { + MapProblemPreference map = (MapProblemPreference) problem + .getPreference(); + if (map == null) { + map = new MapProblemPreference(AbstractProblemPreference.PARAM, ""); //$NON-NLS-1$ + if (problem instanceof IProblemWorkingCopy) { + ((IProblemWorkingCopy) problem).setPreference(map); + } + } + return map; + } + + /** + * Returns value of the preference for the key in the top level + * preference map for the given problem + * + * @param problem - problem for which to get the preference + * @param key - preference key + * @return value of the preference + */ + public Object getPreference(IProblem problem, String key) { + return ((MapProblemPreference) problem.getPreference()) + .getChildValue(key); + } +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractIndexAstChecker.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractIndexAstChecker.java deleted file mode 100644 index d805f2f..0000000 --- a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractIndexAstChecker.java +++ /dev/null @@ -1,103 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009 Alena Laskavaia - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alena Laskavaia - initial API and implementation - *******************************************************************************/ -package org.eclipse.cdt.codan.core.model; - -import org.eclipse.cdt.codan.core.CodanCorePlugin; -import org.eclipse.cdt.core.CCorePlugin; -import org.eclipse.cdt.core.dom.ast.IASTFileLocation; -import org.eclipse.cdt.core.dom.ast.IASTNode; -import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; -import org.eclipse.cdt.core.index.IIndex; -import org.eclipse.cdt.core.model.CoreModel; -import org.eclipse.cdt.core.model.ICElement; -import org.eclipse.cdt.core.model.ITranslationUnit; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.Path; - -/** - * @author Alena - * - */ -public abstract class AbstractIndexAstChecker extends AbstractChecker implements - ICAstChecker { - private IFile file; - - protected IFile getFile() { - return file; - } - - void processFile(IFile file) throws CoreException, InterruptedException { - // create translation unit and access index - ICElement model = CoreModel.getDefault().create(file); - if (!(model instanceof ITranslationUnit)) - return; - ITranslationUnit tu = (ITranslationUnit) model; - if (tu == null) - return; // not a C/C++ file - IIndex index = CCorePlugin.getIndexManager().getIndex(tu.getCProject()); - // lock the index for read access - index.acquireReadLock(); - try { - // create index based ast - IASTTranslationUnit ast = tu.getAST(index, - ITranslationUnit.AST_SKIP_INDEXED_HEADERS); - // traverse the ast using the visitor pattern. - this.file = file; - processAst(ast); - } finally { - this.file = null; - index.releaseReadLock(); - } - } - - public boolean processResource(IResource resource) { - if (resource instanceof IFile) { - IFile file = (IFile) resource; - try { - processFile(file); - } catch (CoreException e) { - CodanCorePlugin.log(e); - } catch (InterruptedException e) { - // ignore - } - return false; - } - return true; - } - - public void reportProblem(String id, IASTNode astNode, String message) { - IASTFileLocation astLocation = astNode.getFileLocation(); - IPath location = new Path(astLocation.getFileName()); - IFile astFile = ResourcesPlugin.getWorkspace().getRoot() - .getFileForLocation(location); - if (astFile == null) { - astFile = file; - } - ProblemLocation loc; - if (astLocation.getStartingLineNumber() == astLocation - .getEndingLineNumber()) - loc = new ProblemLocation(astFile, astLocation.getNodeOffset(), - astLocation.getNodeOffset() + astLocation.getNodeLength()); - else - loc = new ProblemLocation(astFile, astLocation - .getStartingLineNumber()); - getProblemReporter().reportProblem(id, loc, message); - } - - @Override - public boolean runInEditor() { - return true; - } -} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractProblemLocation.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractProblemLocation.java new file mode 100644 index 0000000..c2bcd2a --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractProblemLocation.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Alena Laskavaia + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.model; + +import org.eclipse.core.resources.IFile; + +/** + * Abstract Implementation of IProblemLocation + * + * Clients may extend this class. + *

+ * EXPERIMENTAL. This class or interface has been added as + * part of a work in progress. There is no guarantee that this API will + * work or that it will remain the same. + *

+ */ +public abstract class AbstractProblemLocation implements IProblemLocation { + protected IFile file; + protected int line; + protected int posStart; + protected int posEnd; + protected Object extra; + + protected AbstractProblemLocation(IFile file, int line) { + this.file = file; + this.line = line; + this.posStart = -1; + this.posEnd = -1; + } + + protected AbstractProblemLocation(IFile file, int startChar, int endChar) { + this.file = file; + this.line = -1; + this.posStart = startChar; + this.posEnd = endChar; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.codan.core.model.IProblemLocation#getData() + */ + public Object getData() { + return extra; + } + + /** + * Sets extra data for the problem location + * + * @param data + */ + public void setData(Object data) { + this.extra = data; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.codan.core.model.IProblemLocation#getFile() + */ + public IFile getFile() { + return file; + } + + /** + * Problem line number referenced in problem view in location field + */ + public int getLineNumber() { + return getStartingLineNumber(); + } + + /** + * @return line number where problem starts + */ + public int getStartingLineNumber() { + return line; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.codan.core.model.IProblemLocation#getStartPos() + */ + public int getStartingChar() { + return posStart; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.codan.core.model.IProblemLocation#getEndingChar() + */ + public int getEndingChar() { + return posEnd; + } +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/CVS/Entries b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/CVS/Entries index 8635b9d..4315bc4 100644 --- a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/CVS/Entries +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/CVS/Entries @@ -1,16 +1,19 @@ -/AbstractChecker.java/1.4/Sat Aug 22 21:31:29 2009// -/AbstractIndexAstChecker.java/1.6/Wed Dec 16 21:48:48 2009// -/CodanSeverity.java/1.2/Wed Apr 22 01:26:56 2009// -/ICAstChecker.java/1.1/Thu Apr 9 12:46:50 2009// -/IChecker.java/1.3/Wed Dec 16 21:48:48 2009// -/ICheckersRegistry.java/1.1/Sat Aug 22 21:16:48 2009// -/ICodanAstReconciler.java/1.1/Sat Aug 22 21:16:48 2009// -/ICodanBuilder.java/1.1/Sat Aug 22 21:16:48 2009// -/IProblem.java/1.4/Wed Dec 16 21:48:48 2009// -/IProblemCategory.java/1.3/Wed Dec 16 21:48:48 2009// -/IProblemElement.java/1.2/Wed Dec 16 21:48:48 2009// -/IProblemLocation.java/1.1/Sat Aug 22 21:16:48 2009// -/IProblemProfile.java/1.4/Wed Dec 16 21:48:48 2009// -/IProblemReporter.java/1.2/Wed Dec 16 21:48:48 2009// -/ProblemLocation.java/1.1/Sat Aug 22 21:16:48 2009// -D +/AbstractChecker.java/1.13/Sun Jun 27 01:30:41 2010//TCDT_7_0_0 +/AbstractCheckerWithProblemPreferences.java/1.5/Mon May 31 02:53:25 2010//TCDT_7_0_0 +/AbstractProblemLocation.java/1.3/Sun Jun 27 01:30:41 2010//TCDT_7_0_0 +/CodanSeverity.java/1.6/Sun Jun 27 01:30:41 2010//TCDT_7_0_0 +/IChecker.java/1.8/Sun Jun 27 01:30:41 2010//TCDT_7_0_0 +/ICheckerWithPreferences.java/1.3/Thu Jun 3 17:01:52 2010//TCDT_7_0_0 +/ICheckersRegistry.java/1.6/Sun Jun 27 01:30:41 2010//TCDT_7_0_0 +/ICodanBuilder.java/1.4/Sun Jun 27 01:30:41 2010//TCDT_7_0_0 +/IProblem.java/1.13/Sun Jun 27 01:30:41 2010//TCDT_7_0_0 +/IProblemCategory.java/1.7/Sun Jun 27 01:30:41 2010//TCDT_7_0_0 +/IProblemElement.java/1.4/Sun Jun 27 01:30:41 2010//TCDT_7_0_0 +/IProblemLocation.java/1.4/Sun Jun 27 01:30:41 2010//TCDT_7_0_0 +/IProblemLocationFactory.java/1.5/Sun Jun 27 01:30:41 2010//TCDT_7_0_0 +/IProblemProfile.java/1.8/Sun Jun 27 01:30:41 2010//TCDT_7_0_0 +/IProblemReporter.java/1.6/Sun Jun 27 01:30:41 2010//TCDT_7_0_0 +/IProblemReporterPersistent.java/1.3/Sun Jun 27 01:30:41 2010//TCDT_7_0_0 +/IProblemWorkingCopy.java/1.9/Sun Jun 27 01:30:41 2010//TCDT_7_0_0 +/IRunnableInEditorChecker.java/1.3/Sun Jun 27 01:30:41 2010//TCDT_7_0_0 +D/cfg//// diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/CVS/Tag b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/CVS/Tag new file mode 100644 index 0000000..49a449a --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/CVS/Tag @@ -0,0 +1 @@ +NCDT_7_0_0 diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/CodanSeverity.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/CodanSeverity.java index acfa4d1..fb85718 100644 --- a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/CodanSeverity.java +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/CodanSeverity.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Alena Laskavaia + * Copyright (c) 2009, 2010 Alena Laskavaia * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -12,21 +12,40 @@ package org.eclipse.cdt.codan.core.model; import org.eclipse.core.resources.IMarker; +/** + * + * Represents Severity of the codan problem. It is directly mapped to markers + * severity. + * + */ public enum CodanSeverity { - Info(IMarker.SEVERITY_INFO), Warning(IMarker.SEVERITY_WARNING), Error( - IMarker.SEVERITY_ERROR); + /** + * Info severity + */ + Info(IMarker.SEVERITY_INFO), + /** + * Warning severity + */ + Warning(IMarker.SEVERITY_WARNING), + /** + * Error severity + */ + Error(IMarker.SEVERITY_ERROR); private int value; private CodanSeverity(int value) { this.value = value; } + /** + * @return int value of the severity + */ public int intValue() { return value; } /** - * @return + * @return array of string value for all severities */ public static String[] stringValues() { CodanSeverity[] values = values(); diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ICAstChecker.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ICAstChecker.java deleted file mode 100644 index 461c0fa..0000000 --- a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ICAstChecker.java +++ /dev/null @@ -1,21 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009 Alena Laskavaia - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alena Laskavaia - initial API and implementation - *******************************************************************************/ -package org.eclipse.cdt.codan.core.model; - -import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; - -/** - * @author Alena - * - */ -public interface ICAstChecker extends IChecker { - void processAst(IASTTranslationUnit ast); -} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IChecker.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IChecker.java index 60f7cb2..f00fea0 100644 --- a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IChecker.java +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IChecker.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Alena Laskavaia + * Copyright (c) 2009, 2010 Alena Laskavaia * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -13,27 +13,48 @@ package org.eclipse.cdt.codan.core.model; import org.eclipse.core.resources.IResource; /** - * Interface that checker must implement. CDT Checker must be able to process a resource. + * Interface that checker must implement (through extending directly or + * indirectly {@link AbstractChecker}. + * + *

+ * EXPERIMENTAL. This class or interface has been added as part + * of a work in progress. There is no guarantee that this API will work or that + * it will remain the same. + *

+ * + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + * Extend {@link AbstractChecker} class instead. */ public interface IChecker { /** * Main method that checker should implement that actually detects errors - * @param resource - resource to run on - * @return true if need to traverse children + * + * @param resource + * - resource to run on + * @return true if framework should traverse children of the resource and + * run this checkers on them again */ boolean processResource(IResource resource); /** - * Implement this method to trim down type of resource you are interested in, - * usually it will be c/c++ files only + * Implement this method to trim down type of resource you are interested + * in, usually it will be c/c++ files only. This method should be + * independent from current user preferences. + * * @param resource - * @return + * - resource to run on + * @return - true if checker should be run on this resource */ boolean enabledInContext(IResource resource); /** * Checker must implement this method to determine if it can run in editor - * "as you type", checker must be really light weight to run in this mode + * "as you type". Checker must be really light weight to run in this mode. + * If it returns true, checker must also implement + * {@link IRunnableInEditorChecker}. + * Checker should return false if check is non-trivial and takes a long + * time. * * @return true if need to be run in editor as user types, and false * otherwise diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ICheckerWithPreferences.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ICheckerWithPreferences.java new file mode 100644 index 0000000..56619cb --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ICheckerWithPreferences.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Alena Laskavaia + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.model; + +/** + * Interface for checker with parameters, if checker implements this interface + * method would be called on initialization so checker has a chance to set + * default values for its parameters. It is recommended to use + * {@link AbstractCheckerWithProblemPreferences} insted of implementing it + * directly.

+ * EXPERIMENTAL. This class or interface has been added as part + * of a work in progress. There is no guarantee that this API will work or that + * it will remain the same. + *

+ * + * @noextend This interface is not intended to be extended by clients. + */ +public interface ICheckerWithPreferences { + /** + * Implement this method to set default parameters for checkers with + * parameters. + * + * @param problem + * - instance of problem working copy + */ + void initPreferences(IProblemWorkingCopy problem); +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ICheckersRegistry.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ICheckersRegistry.java index 052d868..04189ae 100644 --- a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ICheckersRegistry.java +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ICheckersRegistry.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Alena Laskavaia + * Copyright (c) 2009, 2010 Alena Laskavaia * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,57 +10,125 @@ *******************************************************************************/ package org.eclipse.cdt.codan.core.model; +import java.util.Collection; import java.util.Iterator; import org.eclipse.core.resources.IResource; /** - * @author Alena + * This interface an API to add/remove checker and problems programmatically, + * get problem profiles and change problem default settings + * + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. * */ -public interface ICheckersRegistry { - public abstract Iterator iterator(); +public interface ICheckersRegistry extends Iterable { + /** + * Iterator for registered checkers + * + * @return iterator for registered checkers + */ + public Iterator iterator(); + + /** + * Add a checker + * + * @param checker instance + */ + public void addChecker(IChecker checker); - public abstract void addChecker(IChecker checker); + /** + * Add problem p into a category defined by a category id into default + * profile, category must exists in default profile + * + * @param p + * - problem + * @param categoryId + * - category id + */ + public void addProblem(IProblem p, String categoryId); - public abstract void addProblem(IProblem p, String category); + /** + * Add subcategory category into parent category with the id of + * parentCategoryId, if parent does not exist in the default profile or it + * is a null - it will be added to the root + * + * @param category + * - new category + * @param parentCategoryId + * - parent category id + */ + public abstract void addCategory(IProblemCategory category, + String parentCategoryId); - public abstract void addCategory(IProblemCategory p, String category); + /** + * Add problem reference to a checker, i.e. claim that checker can produce + * this problem. If checker does not claim any problems it cannot be + * enabled. + * + * @param c + * - checker + * @param p + * - problem + */ + public void addRefProblem(IChecker c, IProblem p); - public abstract void addRefProblem(IChecker c, IProblem p); + /** + * Return collection of problem that this checker can produce + * + * @param checker + * @return collection of problems + */ + public Collection getRefProblems(IChecker checker); /** - * @return + * Default profile is kind of "Installation Default". + * Always the same, comes from defaults in checker extensions or APIs added + * + * @return default profile */ - public abstract IProblemProfile getDefaultProfile(); + public IProblemProfile getDefaultProfile(); /** - * @return + * Get workspace profile. User can change setting for workspace profile. + * + * @return workspace profile */ - public abstract IProblemProfile getWorkspaceProfile(); + public IProblemProfile getWorkspaceProfile(); /** + * Get resource profile. For example given project can have different + * profile than a workspace. + * * @param element - * @return + * - resource + * @return resource profile */ - public abstract IProblemProfile getResourceProfile(IResource element); + public IProblemProfile getResourceProfile(IResource element); /** + * Returns profile working copy for given resource element. (If profile is + * not specified for given element it will search for parent resource and so + * on). If you planning on editing it this method should be used instead of + * getResourceProfile. You have to save your changes after updating a + * working copy, using {@link #updateProfile(IResource, IProblemProfile)} + * method. + * + * @noreference This method is not intended to be referenced by clients. * @param element - * @return + * @return resource profile */ - public abstract IProblemProfile getResourceProfileWorkingCopy( - IResource element); + public IProblemProfile getResourceProfileWorkingCopy(IResource element); /** - * Set profile for resource. This method is called by UI, and should not be - * called by clients directly + * Set profile for resource. * + * @noreference This method is not intended to be referenced by clients. * @param resource - * - resource + * - resource * @param profile - * - problems profile + * - problems profile */ - public abstract void updateProfile(IResource resource, - IProblemProfile profile); + public void updateProfile(IResource resource, IProblemProfile profile); } \ No newline at end of file diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ICodanAstReconciler.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ICodanAstReconciler.java deleted file mode 100644 index 17bc8f7..0000000 --- a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ICodanAstReconciler.java +++ /dev/null @@ -1,22 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009 Alena Laskavaia - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alena Laskavaia - initial API and implementation - *******************************************************************************/ -package org.eclipse.cdt.codan.core.model; - -import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; -import org.eclipse.core.runtime.IProgressMonitor; - -/** - * @author Alena - * - */ -public interface ICodanAstReconciler { - public void reconcileAst(IASTTranslationUnit ast, IProgressMonitor monitor); -} \ No newline at end of file diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ICodanBuilder.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ICodanBuilder.java index ce1f668..dcbe4c3 100644 --- a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ICodanBuilder.java +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ICodanBuilder.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Alena Laskavaia + * Copyright (c) 2009, 2010 Alena Laskavaia * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -14,9 +14,20 @@ import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IProgressMonitor; /** - * @author Alena + * Interface for "Codan Builder". Clients can call processResource method to + * traverse the resource tree. It will be calling all the checkers (this + * interface allows to call framework without using UI). You can obtain instance + * of this class as CodanRuntime.getInstance().getBuilder() * + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. */ public interface ICodanBuilder { + /** + * Run code analysis on given resource + * + * @param resource - resource to process + * @param monitor - progress monitor + */ public void processResource(IResource resource, IProgressMonitor monitor); } \ No newline at end of file diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblem.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblem.java index bbab313..d12806d 100644 --- a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblem.java +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblem.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Alena Laskavaia + * Copyright (c) 2009, 2010 Alena Laskavaia * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,56 +10,82 @@ *******************************************************************************/ package org.eclipse.cdt.codan.core.model; -import java.util.Collection; +import org.eclipse.cdt.codan.core.param.IProblemPreference; /** - * Interface representing code analysis problem - * + * Interface representing code analysis problem type. For example + * "Null Pointer Dereference" is a problem. It has user visible Name and Message + * (translatable), as well as some other parameters, changeable by user such as + * enablement, severity and so on. Same problem cannot have two severities + * determined by runtime. If it is the case - two Problems should be created + * (i.e. one for error and one for warning). All of problem attributes are + * defined in a checker extension point. + * + *

+ * EXPERIMENTAL. This class or interface has been added as part + * of a work in progress. There is no guarantee that this API will work or that + * it will remain the same. + *

+ * + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. */ public interface IProblem extends IProblemElement { /** * Name of the problem - user visible "title", not the message + * + * @return title of the problem */ String getName(); /** - * Unique problem id. Should be qualified by plugin name to maintain uniqueness. - * @return + * Unique problem id. Should be qualified by plugin name to maintain + * uniqueness. + * + * @return unique problem id */ String getId(); /** * Is enabled in current context (usually within profile) + * * @return true if enabled */ boolean isEnabled(); /** * Get current severity + * * @return severity */ CodanSeverity getSeverity(); /** * Message pattern, java patter like 'Variable {0} is never used here' - * @return pattern + * + * @return pattern */ String getMessagePattern(); - void setSeverity(CodanSeverity sev); - - void setEnabled(boolean checked); - - void setMessagePattern(String message); - - public void setProperty(Object key, Object value); + /** + * Get root preference descriptor or null if not defined (used by ui to + * generate user controls for changing parameters) + * + * @return root preference or null + */ + public IProblemPreference getPreference(); /** - * Get custom property - * @param property name - * @return property object + * Get short description of a problem + * + * @return description */ - public Object getProperty(Object key); + public String getDescription(); - public Collection getPropertyKeys(); + /** + * Return marker id for the problem + * + * @return marker id + */ + public String getMarkerType(); } diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemCategory.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemCategory.java index cd3de3a..adfc897 100644 --- a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemCategory.java +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemCategory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Alena Laskavaia + * Copyright (c) 2009, 2010 Alena Laskavaia * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -11,38 +11,35 @@ package org.eclipse.cdt.codan.core.model; /** - * Problem category - * + * Problem category. Allows to group problems. + *

+ * EXPERIMENTAL. This class or interface has been added as part + * of a work in progress. There is no guarantee that this API will work or that + * it will remain the same. + *

+ * + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. */ public interface IProblemCategory extends IProblemElement { /** * Category name + * + * @return category name */ String getName(); /** * Unique category id + * * @return id */ String getId(); /** * Category children (other categories or problems) - * @return + * + * @return children of the category */ IProblemElement[] getChildren(); - - /** - * Find problem by id within children recursively - * @param id - * @return - */ - IProblem findProblem(String id); - - /** - * Find category by id within children recursively - * @param id - * @return - */ - IProblemCategory findCategory(String id); } diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemElement.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemElement.java index 318f304..3068aeb 100644 --- a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemElement.java +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemElement.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Alena Laskavaia + * Copyright (c) 2009, 2010 Alena Laskavaia * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -11,9 +11,17 @@ package org.eclipse.cdt.codan.core.model; /** - * Problem category or problem + * Problem category {@link IProblemCategory} or problem {@link IProblem} * + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. */ public interface IProblemElement extends Cloneable { + /** + * clone method should be implemented to support problem cloning + * @see {@link Object#clone} + * @return new object which is copy of this one + * @throws CloneNotSupportedException - it is declared with this exception but it should NOT throw it + */ Object clone() throws CloneNotSupportedException; } diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemLocation.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemLocation.java index f5e4f23..1ef8546 100644 --- a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemLocation.java +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemLocation.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Alena Laskavaia + * Copyright (c) 2009, 2010 Alena Laskavaia * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,19 +10,21 @@ *******************************************************************************/ package org.eclipse.cdt.codan.core.model; -import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; /** * Interface to describe problem location. Usually contains file and linenumber, * also supports character positions for sophisticated errors. * + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. */ public interface IProblemLocation { /** * * @return File for the problem - absolute full paths */ - IFile getFile(); + IResource getFile(); /** * diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemLocationFactory.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemLocationFactory.java new file mode 100644 index 0000000..4710bb1 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemLocationFactory.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Alena Laskavaia + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.model; + +import org.eclipse.core.resources.IFile; + +/** + * Factory interface that allows to create problem locations. + * + * Clients may implement and extend this interface. + *

+ * EXPERIMENTAL. This class or interface has been added as part + * of a work in progress. There is no guarantee that this API will work or that + * it will remain the same. + *

+ */ +public interface IProblemLocationFactory { + /** + * Create and return instance of IProblemLocation + * + * @param file + * - file where problem is found + * @param line + * - line number where problem is found, starts with 1 + * @return instance of IProblemLocation + */ + public IProblemLocation createProblemLocation(IFile file, int line); + + /** + * Create and return instance of IProblemLocation + * + * @param file + * - file where problem is found + * @param startChar + * - start char of the problem in the file, is zero-relative + * @param endChar + * - end char of the problem in the file, is zero-relative and + * exclusive. + * @return instance of IProblemLocation + */ + public IProblemLocation createProblemLocation(IFile file, int startChar, + int endChar); + + /** + * Create and return instance of IProblemLocation + * + * @param astFile - file where problem is found + * @param startChar - start char of the problem in the file, is + * zero-relative + * @param endChar - end char of the problem in the file, is zero-relative and + * exclusive. + * + * @param line + * - start line number (for visualisation purposes) + * @return instance of IProblemLocation + */ + public IProblemLocation createProblemLocation(IFile astFile, + int startChar, int endChar, int line); +} \ No newline at end of file diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemProfile.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemProfile.java index 896eb10..1a0d2df 100644 --- a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemProfile.java +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemProfile.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Alena Laskavaia + * Copyright (c) 2009, 2010 Alena Laskavaia * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,16 +10,29 @@ *******************************************************************************/ package org.eclipse.cdt.codan.core.model; +import org.eclipse.cdt.codan.internal.core.CheckersRegistry; + /** - * Problem Profile contains tree of categories and problems. For user profile is quick way - * to switch between problems sets depends on task he is doing (i.e. find real bugs, vs doing code style report) - * User can set different profiles in different projects. - * Profiles can have different categories and different problems set, problems with the same id - * can have different severities/enablement in different profiles. To obtain - * profile use class {@link CheckersRegisry#getResourceProfile, - * CheckersRegisry#getDefaultProfile() or CheckersRegisry#getWorkspaceProfile()} - * . + * Problem Profile contains tree of categories and problems. For the user + * the profile is quick way to switch between problem sets depending on the + * task he is doing (i.e. find real bugs, vs doing code style report) + * User can set different profiles for different projects. + * Profiles can have different categories and different problem sets, + * problems with the same id can have different severities/enablement in + * different profiles. + * Category tree can have few reference to a same problem, but only instance of + * Problem + * with the same id can exist in the same profile (i.e. two category can have + * same problem listed in both, + * but they both should point to the same problem instance). + * + * To obtain read-only profile use method + * {@link CheckersRegistry#getResourceProfile}, + * {@link CheckersRegistry#getDefaultProfile()} or + * {@link CheckersRegistry#getWorkspaceProfile()} * + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. */ public interface IProblemProfile extends IProblemElement { /** @@ -28,25 +41,26 @@ public interface IProblemProfile extends IProblemElement { IProblemCategory getRoot(); /** - * Find and return problem by id + * Find and return problem by id if it contained in this profile * * @param id - * - problem id + * - problem id * @return problem instance */ IProblem findProblem(String id); /** - * Find and return category by id + * Find and return category by id if it is contained in this profile * * @param id - * - category id + * - category id * @return category instance */ IProblemCategory findCategory(String id); /** - * Get all defined problems + * Get all problems defined in this profile (if problem duplicated in a + * category tree, it returns only one instance of each) * * @return array of problems defined in profile */ diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemReporter.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemReporter.java index 059f155..a928593 100644 --- a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemReporter.java +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemReporter.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Alena Laskavaia + * Copyright (c) 2009, 2010 Alena Laskavaia * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,20 +10,32 @@ *******************************************************************************/ package org.eclipse.cdt.codan.core.model; - /** * IProblemReporter - interface to report problems - * + * + *

+ * EXPERIMENTAL. This class or interface has been added as + * part of a work in progress. There is no guarantee that this API will + * work or that it will remain the same. + *

*/ public interface IProblemReporter { - public static final String GENERIC_CODE_ANALYSIS_MARKER_TYPE = "org.eclipse.cdt.codan.core.codanProblem"; /** - * Report a problem with "problemId" id on location determined by "loc", - * using problem specific error message customised by args. - * @param problemId - id of the problem registers with checker - * @param loc - location object - * @param args - custom args, can be null, in this case default message is reported + * id of generic codan problem marker + */ + public static final String GENERIC_CODE_ANALYSIS_MARKER_TYPE = "org.eclipse.cdt.codan.core.codanProblem"; //$NON-NLS-1$ + + /** + * Report a problem with "problemId" id on the location determined by "loc", + * using problem specific error message customized by args. + * + * @param problemId - id of the problem registered with a checker + * @param loc - location object, can be created using + * getRuntime().getProblemLocationFactory().createProblemLocation + * methods + * @param args - custom arguments, can be null, in this case default message + * is reported */ - public void reportProblem(String problemId, IProblemLocation loc, - Object ... args); + public void reportProblem(String problemId, IProblemLocation loc, + Object... args); } \ No newline at end of file diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemReporterPersistent.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemReporterPersistent.java new file mode 100644 index 0000000..88638d9 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemReporterPersistent.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Alena Laskavaia + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.model; + +import org.eclipse.core.resources.IResource; + +/** + * IProblemReporterPersistent - interface to report problems, which are + * persistent, ex. markers + * + *

+ * EXPERIMENTAL. This class or interface has been added as part + * of a work in progress. There is no guarantee that this API will work or that + * it will remain the same. + *

+ */ +public interface IProblemReporterPersistent extends IProblemReporter { + /** + * Delete all problems associated with resource created by given checker + * + * @param resource + * @param checker + */ + public void deleteProblems(IResource resource, IChecker checker); + + /** + * Delete all problems associated with resource + * + * @param resource + */ + public void deleteProblems(IResource resource); + + /** + * Delete all persisted problems + */ + public void deleteAllProblems(); +} \ No newline at end of file diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemWorkingCopy.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemWorkingCopy.java new file mode 100644 index 0000000..bb08f2e --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IProblemWorkingCopy.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Alena Laskavaia + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.model; + +import org.eclipse.cdt.codan.core.param.IProblemPreference; + +/** + * Modifiable problem. + * + * + *

+ * EXPERIMENTAL. This class or interface has been added as part + * of a work in progress. There is no guarantee that this API will work or that + * it will remain the same. + *

+ * + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IProblemWorkingCopy extends IProblem { + /** + * Set severity for this this problem instance. Severity can only be changed + * in profile not by checker when printing problems. + * + * @param sev + * - codan severity + */ + void setSeverity(CodanSeverity sev); + + /** + * Set checker enablement. + * + * @param enabled + * - true if problem is enabled in profile + */ + void setEnabled(boolean enabled); + + /** + * Set default message pattern. UI would call this method if user does not + * like default settings, checker should not use method, default message + * pattern should be set in checker extension + * + * @param messagePattern + * - java style message patter i.e. "Variable {0} is never used" + */ + void setMessagePattern(String messagePattern); + + /** + * Set value for the checker parameter, checker may set value during + * initialization only, which would the default. User control this values + * through ui later. + * + * @param pref - preference to set + * + */ + public void setPreference(IProblemPreference pref); + + /** + * Set problem description + * + * @param desc + * - problem description - short version, but longer than name + */ + public void setDescription(String desc); +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IRunnableInEditorChecker.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IRunnableInEditorChecker.java new file mode 100644 index 0000000..694aaf4 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/IRunnableInEditorChecker.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Alena Laskavaia + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.model; + +/** + * Interface for checkers that can be run when user is typing, checker has to be + * very quick to run in this mode + *

+ * EXPERIMENTAL. This class or interface has been added as part + * of a work in progress. There is no guarantee that this API will work or that + * it will remain the same. + *

+ * + * @noextend This interface is not intended to be extended by clients. + */ +public interface IRunnableInEditorChecker { + /** + * @param model + */ + void processModel(Object model); +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ProblemLocation.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ProblemLocation.java deleted file mode 100644 index ced12f0..0000000 --- a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ProblemLocation.java +++ /dev/null @@ -1,109 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009 Alena Laskavaia - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alena Laskavaia - initial API and implementation - *******************************************************************************/ -package org.eclipse.cdt.codan.core.model; - -import org.eclipse.core.resources.IFile; - -/** - * Implementation of IProblemLocation - * - */ -public class ProblemLocation implements IProblemLocation { - protected IFile file; - protected int line; - protected int posStart; - protected int posEnd; - protected Object extra; - - /** - * @param file - * @param line - * @param lineEnd - * @param posStart - * @param posEnd - */ - public ProblemLocation(IFile file, int line) { - this.file = file; - this.line = line; - this.posStart = -1; - this.posEnd = -1; - } - - /** - * @param file - * @param startingLineNumber - * @param endingLineNumber - */ - public ProblemLocation(IFile file, int startChar, int endChar) { - this.file = file; - this.line = -1; - this.posStart = startChar; - this.posEnd = endChar; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.codan.core.model.IProblemLocation#getData() - */ - public Object getData() { - return extra; - } - - public void setData(Object data) { - this.extra = data; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.codan.core.model.IProblemLocation#getFile() - */ - public IFile getFile() { - return file; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.codan.core.model.IProblemLocation#getLine() - */ - public int getLineNumber() { - return getStartingLineNumber(); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.codan.core.model.IProblemLocation#getStartLine() - */ - public int getStartingLineNumber() { - return line; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.codan.core.model.IProblemLocation#getStartPos() - */ - public int getStartingChar() { - return posStart; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.codan.core.model.IProblemLocation#getEndingChar() - */ - public int getEndingChar() { - return posEnd; - } -} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/CVS/Entries b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/CVS/Entries new file mode 100644 index 0000000..60f510d --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/CVS/Entries @@ -0,0 +1,13 @@ +/IBasicBlock.java/1.6/Thu Jun 3 17:01:53 2010//TCDT_7_0_0 +/IBranchNode.java/1.4/Thu Jun 3 17:01:53 2010//TCDT_7_0_0 +/ICfgData.java/1.2/Tue Jun 1 02:24:14 2010//TCDT_7_0_0 +/IConnectorNode.java/1.5/Thu Jun 3 17:01:53 2010//TCDT_7_0_0 +/IControlFlowGraph.java/1.5/Thu Jun 3 17:01:53 2010//TCDT_7_0_0 +/IDecisionNode.java/1.4/Thu Jun 3 17:01:53 2010//TCDT_7_0_0 +/IExitNode.java/1.4/Thu Jun 3 17:01:53 2010//TCDT_7_0_0 +/IJumpNode.java/1.5/Thu Jun 3 17:01:53 2010//TCDT_7_0_0 +/INodeFactory.java/1.4/Thu Jun 3 17:01:53 2010//TCDT_7_0_0 +/IPlainNode.java/1.4/Thu Jun 3 17:01:53 2010//TCDT_7_0_0 +/ISingleIncoming.java/1.4/Thu Jun 3 17:01:53 2010//TCDT_7_0_0 +/ISingleOutgoing.java/1.4/Thu Jun 3 17:01:53 2010//TCDT_7_0_0 +/IStartNode.java/1.3/Thu Jun 3 17:01:53 2010//TCDT_7_0_0 diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/CVS/Repository b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/CVS/Repository new file mode 100644 index 0000000..52814e4 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/CVS/Repository @@ -0,0 +1 @@ +org.eclipse.cdt/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/CVS/Root b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/CVS/Root new file mode 100644 index 0000000..04efa23 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@dev.eclipse.org:/cvsroot/tools diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/CVS/Tag b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/CVS/Tag new file mode 100644 index 0000000..49a449a --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/CVS/Tag @@ -0,0 +1 @@ +NCDT_7_0_0 diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IBasicBlock.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IBasicBlock.java new file mode 100644 index 0000000..406ab84 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IBasicBlock.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2010 Alena Laskavaia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.model.cfg; + +/** + * Control flow graph's basic block node - super interface of all nodes. + * It has set on incoming nodes and outgoing nodes. + *

+ * + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IBasicBlock { + /** + * Incoming nodes - nodes that executed immediately before this one + * + * @return array of incoming nodes, empty array of none + */ + IBasicBlock[] getIncomingNodes(); + + /** + * Outgoing nodes - where control would be passed. Can be more than one if + * node is condition. + * + * @return array of outgoing nodes, empty of none + */ + IBasicBlock[] getOutgoingNodes(); + + /** + * @return size of array of incoming nodes + */ + int getIncomingSize(); + + /** + * @return size of array of outgoing nodes + */ + int getOutgoingSize(); +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IBranchNode.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IBranchNode.java new file mode 100644 index 0000000..77e7fb3 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IBranchNode.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Alena Laskavaia + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.model.cfg; + +/** + * Node that represent empty operator with label, such as case branch or label + * + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IBranchNode extends IBasicBlock, ISingleIncoming, + ISingleOutgoing { + /** + * Then branch of "if" statement + */ + public static String THEN = "then"; //$NON-NLS-1$ + /** + * Else branch of "if" statement + */ + public static String ELSE = "else"; //$NON-NLS-1$ + /** + * Default branch of "switch" statement + */ + public static String DEFAULT = "default"; //$NON-NLS-1$ + + /** + * @return label of a branch + */ + String getLabel(); +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/ICfgData.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/ICfgData.java new file mode 100644 index 0000000..1e43450 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/ICfgData.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2009,2010 Alena Laskavaia + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.model.cfg; + +/** + * Interface to access data object that control flow graph block carries, + * usually it is an ast node. + * + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface ICfgData { + /** + * @return data object + */ + public abstract Object getData(); + + /** + * Sets data object for the node + * + * @param data + */ + public abstract void setData(Object data); +} \ No newline at end of file diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IConnectorNode.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IConnectorNode.java new file mode 100644 index 0000000..f58fdd1 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IConnectorNode.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2010 Alena Laskavaia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.model.cfg; + +/** + * Connector node has multiple incoming branches and single outgoing. + * Incoming nodes are usually instance of {@link IJumpNode} + * + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IConnectorNode extends IBasicBlock, ISingleOutgoing { + /** + * @return true if one of the incoming arcs is backward arc + */ + boolean hasBackwardIncoming(); +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IControlFlowGraph.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IControlFlowGraph.java new file mode 100644 index 0000000..a8f9269 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IControlFlowGraph.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Alena Laskavaia + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.model.cfg; + +import java.util.Collection; +import java.util.Iterator; + +/** + * Represents control flow graph (CFG) object. + * This is "normalized" control flow graph, with typed nodes: + *
+ *

  • {@link IStartNode} - start node of the cfg (source) + *
  • {@link IExitNode} - exit node of the cfg (sink) + *
  • {@link IPlainNode} - has one incoming one outgoing + *
  • {@link IDecisionNode} - has one incoming and the only node that can have + * multiple outcoming + * arcs + *
  • {@link IConnectorNode} - the only node that can have multiple incoming + * arcs, and one outgoing + *
  • {@link IJumpNode} - has one incoming and one outgoing but represent + * change of control direction + *
  • {@link IBranchNode} - usually node where decision node connect to, + * labels represent a way where controls goes to + * + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IControlFlowGraph { + /** + * @return start node of the graph. CFG only has one start node. + */ + IStartNode getStartNode(); + + /** + * @return iterator over exit nodes of control flow graph. Exit nodes + * include return statement, + * and statements with throw and abort/exit functions. + */ + Iterator getExitNodeIterator(); + + /** + * @return size of exit nodes list + */ + int getExitNodeSize(); + + /** + * @return list of roots of dead code sections, they don't have incoming + * arcs + */ + Iterator getUnconnectedNodeIterator(); + + /** + * @return size of unconnected nodes list + */ + int getUnconnectedNodeSize(); + + /** + * @return collection of all nodes + */ + Collection getNodes(); +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IDecisionNode.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IDecisionNode.java new file mode 100644 index 0000000..7f2f561 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IDecisionNode.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2010 Alena Laskavaia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.model.cfg; + +/** + * + * Interface for decision node. This node represent condition node in the graph, + * it has one incoming arc and many outgoing, each of outgoing node should be + * IBranchNode + * + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IDecisionNode extends IBasicBlock, ISingleIncoming { + /** + * Node where branches of decision node merge + * + * @return the "merge" node + */ + IConnectorNode getMergeNode(); +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IExitNode.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IExitNode.java new file mode 100644 index 0000000..71d7e25 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IExitNode.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Alena Laskavaia + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.model.cfg; + +/** + * Exit node of the graph. Usually return from the function, can also be throw + * or abort, such at exit(0) call. + * + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IExitNode extends IBasicBlock, ISingleIncoming { + /** + * @return reference to a start node a graph + */ + IStartNode getStartNode(); +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IJumpNode.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IJumpNode.java new file mode 100644 index 0000000..d2e298b --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IJumpNode.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2010 Alena Laskavaia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.model.cfg; + +/** + * Node that changes the control of the graph, i.e. passes control to non-next + * statement. Can be used to implement gotos, break, continue, end of branches. + * Outgoing node is always {@link IConnectorNode} + * + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IJumpNode extends IBasicBlock, ISingleOutgoing { + /** + * @return true of outgoing arc is backward one, see definition of backward + * arc in a "network" graph + */ + boolean isBackwardArc(); + + /** + * @return reference to a connector node to which this one "jumps" (same as + * outgoing node) + */ + IConnectorNode getJumpNode(); +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/INodeFactory.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/INodeFactory.java new file mode 100644 index 0000000..bd10ded --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/INodeFactory.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Alena Laskavaia + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.model.cfg; + +/** + * Control Flow Graph Node factory + * + * @noextend This interface is not intended to be extended by clients. + */ +public interface INodeFactory { + /** + * @return new plain node + */ + IPlainNode createPlainNode(); + + /** + * @return new jump node + */ + IJumpNode createJumpNode(); + + /** + * @return new decision node + */ + IDecisionNode createDecisionNode(); + + /** + * @return new connector node + */ + IConnectorNode createConnectorNode(); + + /** + * @param label + * @return new branch node + */ + IBranchNode createBranchNode(String label); + + /** + * @return new start node + */ + IStartNode createStartNode(); + + /** + * @return new exit node + */ + IExitNode createExitNode(); +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IPlainNode.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IPlainNode.java new file mode 100644 index 0000000..fac5599 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IPlainNode.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2010 Alena Laskavaia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.model.cfg; + +/** + * Has one incoming, one outgoing connection. Usually expression statement or + * declaration. + * + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IPlainNode extends IBasicBlock, ISingleOutgoing, + ISingleIncoming { +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/ISingleIncoming.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/ISingleIncoming.java new file mode 100644 index 0000000..2900ce8 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/ISingleIncoming.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2010 Alena Laskavaia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.model.cfg; + +/** + * Node with one incoming arc + * + * @noextend This interface is not intended to be extended by clients. + */ +public interface ISingleIncoming { + /** + * @return single incoming node + */ + IBasicBlock getIncoming(); +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/ISingleOutgoing.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/ISingleOutgoing.java new file mode 100644 index 0000000..3427826 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/ISingleOutgoing.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2010 Alena Laskavaia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.model.cfg; + +/** + * Node with one outgoing arc + * + * @noextend This interface is not intended to be extended by clients. + */ +public interface ISingleOutgoing { + /** + * @return outgoing node + */ + IBasicBlock getOutgoing(); +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IStartNode.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IStartNode.java new file mode 100644 index 0000000..7c20c3e --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IStartNode.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2010 Alena Laskavaia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.model.cfg; + +/** + * Start node of the control flow graph. Each graph has only one start node. It + * has no incoming arcs and one outgoing arc. It also contains iterator for + * function exit nodes. + * + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IStartNode extends IBasicBlock, ISingleOutgoing { +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/AbstractProblemPreference.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/AbstractProblemPreference.java new file mode 100644 index 0000000..91969fc --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/AbstractProblemPreference.java @@ -0,0 +1,202 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Alena Laskavaia + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.param; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.StreamTokenizer; + +/** + * Default implementation of problem preference. It keeps preference metadata + * together with preference value. Some implementations may separate them. + * + */ +public abstract class AbstractProblemPreference implements IProblemPreference { + /** + * default key for a preference + */ + public static final String PARAM = "params"; //$NON-NLS-1$ + private String key = PARAM; + private String label = ""; //$NON-NLS-1$ + private String toolTip = null; + private String uiInfo; + private IProblemPreference parent; + + public String getLabel() { + return label; + } + + public String getToolTip() { + return toolTip; + } + + public String getKey() { + return key; + } + + public String getUiInfo() { + return uiInfo; + } + + /** + * Set preference key for itself + * + * @param key + */ + public void setKey(String key) { + if (key == null) + throw new NullPointerException("key"); //$NON-NLS-1$ + if (isValidIdentifier(key)) + this.key = key; + else + throw new IllegalArgumentException( + "Key must have java identifier syntax or number, i.e no dots and other funky stuff: " + key); //$NON-NLS-1$ + } + + protected boolean isValidIdentifier(String id) { + if (id == null) + return false; + int n = id.length(); + if (n == 0) + return false; + if (id.equals("#")) //$NON-NLS-1$ + return true; + for (int i = 0; i < n; i++) + if (!Character.isJavaIdentifierPart(id.charAt(i))) + return false; + return true; + } + + /** + * Sets a label for UI control + * + * @param label + */ + public void setLabel(String label) { + if (label == null) + throw new NullPointerException("Label cannot be null"); //$NON-NLS-1$ + this.label = label; + } + + /** + * Sets tooltip for ui control. Not supported now. + * + * @param tooltip + */ + public void setToolTip(String tooltip) { + this.toolTip = tooltip; + } + + /** + * Sets uiinfo for ui control. Not supported now. + * + * @param uiinfo + */ + public void setUiInfo(String uiinfo) { + this.uiInfo = uiinfo; + } + + public Object getValue() { + throw new UnsupportedOperationException(); + } + + public void setValue(Object value) { + throw new UnsupportedOperationException(); + } + + @Override + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + return null; + } + } + + /** + * @param str + * @return + */ + protected StreamTokenizer getImportTokenizer(String str) { + ByteArrayInputStream st = new ByteArrayInputStream(str.getBytes()); + StreamTokenizer tokenizer = new StreamTokenizer(new InputStreamReader( + st)); + tokenizer.resetSyntax(); + tokenizer.quoteChar('"'); + tokenizer.wordChars('_', '_'); + tokenizer.wordChars('-', '-'); + tokenizer.wordChars('.', '.'); + tokenizer.wordChars('0', '9'); + tokenizer.wordChars('a', 'z'); + tokenizer.wordChars('A', 'Z'); + tokenizer.wordChars(128 + 32, 255); + tokenizer.whitespaceChars(0, ' '); + tokenizer.commentChar('/'); + return tokenizer; + } + + public IProblemPreference getParent() { + return parent; + } + + /** + * @param parent + * the parent to set + */ + public void setParent(IProblemPreference parent) { + this.parent = parent; + } + + public String getQualifiedKey() { + if (parent == null) + return getKey(); + return parent.getQualifiedKey() + "." + getKey(); //$NON-NLS-1$ + } + + /** + * @param tokenizer + * @throws IOException + */ + public abstract void importValue(StreamTokenizer tokenizer) + throws IOException; + + public void importValue(String str) { + StreamTokenizer tokenizer = getImportTokenizer(str); + try { + importValue(tokenizer); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException(str, e); + } catch (IOException e) { + throw new IllegalArgumentException(e); + } + } + + protected String escape(String x) { + x = x.replaceAll("[\"\\\\]", "\\\\$0"); //$NON-NLS-1$//$NON-NLS-2$ + return "\"" + x + "\""; //$NON-NLS-1$//$NON-NLS-2$ + } + + /** + * @param str + * @return + */ + protected String unescape(String str) { + StreamTokenizer tokenizer = getImportTokenizer(str); + try { + tokenizer.nextToken(); + } catch (IOException e) { + return null; + } + String sval = tokenizer.sval; + return sval; + } +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/BasicProblemPreference.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/BasicProblemPreference.java new file mode 100644 index 0000000..fd146b0 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/BasicProblemPreference.java @@ -0,0 +1,134 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Alena Laskavaia + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.param; + +import java.io.File; +import java.io.IOException; +import java.io.StreamTokenizer; +import java.util.regex.Pattern; + +/** + * Preference representing a problem preference of a basic type. + * + * @see IProblemPreferenceDescriptor.PreferenceType for types. + * + */ +public class BasicProblemPreference extends AbstractProblemPreference { + protected Object value; + private PreferenceType type = PreferenceType.TYPE_STRING; + + public PreferenceType getType() { + return type; + } + + /** + * Set preferene type + * + * @param type + */ + public void setType(PreferenceType type) { + if (type == null) + throw new NullPointerException("Type cannot be null"); //$NON-NLS-1$ + this.type = type; + } + + /** + * Generate an info with given key and label + * + * @param key + * - property id (use in actual property hash of a checker) + * @param label + * - label to be shown to user + * @param type + * - parameter type + */ + public BasicProblemPreference(String key, String label, PreferenceType type) { + this(key, label); + setType(type); + } + + /** + * Generate an info with given key and label + * + * @param key + * - property id (use in actual property hash of a checker) + * @param label + * - label to be shown to user + */ + public BasicProblemPreference(String key, String label) { + setKey(key); + setLabel(label); + } + + @Override + public void setValue(Object value) { + this.value = value; + } + + @Override + public Object getValue() { + return value; + } + + public String exportValue() { + Pattern pat = Pattern.compile("^[A-Za-z0-9._-]+$"); //$NON-NLS-1$ + String x = String.valueOf(getValue()); + if (pat.matcher(x).find() == false) + return escape(x); + return x; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.cdt.codan.core.param.IProblemPreferenceValue#importValue( + * java.lang.String) + */ + @Override + public void importValue(String str) { + if (str.startsWith("\"")) //$NON-NLS-1$ + str = unescape(str); + switch (getType()) { + case TYPE_STRING: + setValue(str); + break; + case TYPE_INTEGER: + setValue(Integer.parseInt(str)); + break; + case TYPE_BOOLEAN: + setValue(Boolean.valueOf(str)); + break; + case TYPE_FILE: + setValue(new File(str)); + break; + default: + throw new IllegalArgumentException(getType() + + " is not supported for basic type"); //$NON-NLS-1$ + } + } + + @Override + public String toString() { + return "(" + type + ")" + getKey() + ((value == null) ? "" : "=" + value); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$ + } + + @Override + public void importValue(StreamTokenizer tokenizer) { + try { + tokenizer.nextToken(); + String val = tokenizer.sval; + importValue(val); + } catch (IOException e) { + new IllegalArgumentException(e); + } + } +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/CVS/Entries b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/CVS/Entries new file mode 100644 index 0000000..4f3cdf4 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/CVS/Entries @@ -0,0 +1,10 @@ +/AbstractProblemPreference.java/1.8/Thu Jun 3 17:01:53 2010//TCDT_7_0_0 +/BasicProblemPreference.java/1.7/Thu Jun 3 17:01:53 2010//TCDT_7_0_0 +/FileScopeProblemPreference.java/1.4/Wed Jun 2 00:39:31 2010//TCDT_7_0_0 +/IProblemPreference.java/1.3/Tue May 25 01:33:22 2010//TCDT_7_0_0 +/IProblemPreferenceCompositeDescriptor.java/1.4/Mon May 31 02:53:25 2010//TCDT_7_0_0 +/IProblemPreferenceCompositeValue.java/1.4/Tue Jun 1 02:24:14 2010//TCDT_7_0_0 +/IProblemPreferenceDescriptor.java/1.6/Thu Jun 3 17:01:53 2010//TCDT_7_0_0 +/IProblemPreferenceValue.java/1.4/Tue Jun 1 02:24:14 2010//TCDT_7_0_0 +/ListProblemPreference.java/1.6/Tue Jun 1 02:24:14 2010//TCDT_7_0_0 +/MapProblemPreference.java/1.6/Tue Jun 1 02:24:14 2010//TCDT_7_0_0 diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/CVS/Repository b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/CVS/Repository new file mode 100644 index 0000000..d959de5 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/CVS/Repository @@ -0,0 +1 @@ +org.eclipse.cdt/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/CVS/Root b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/CVS/Root new file mode 100644 index 0000000..04efa23 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@dev.eclipse.org:/cvsroot/tools diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/CVS/Tag b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/CVS/Tag new file mode 100644 index 0000000..49a449a --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/CVS/Tag @@ -0,0 +1 @@ +NCDT_7_0_0 diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/FileScopeProblemPreference.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/FileScopeProblemPreference.java new file mode 100644 index 0000000..bdb36f0 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/FileScopeProblemPreference.java @@ -0,0 +1,267 @@ +/******************************************************************************* + * Copyright (c) 2009,2010 QNX Software Systems + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems (Alena Laskavaia) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.param; + +import java.io.IOException; +import java.io.StreamTokenizer; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.cdt.codan.core.Messages; +import org.eclipse.cdt.codan.internal.core.CharOperation; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +/** + * Custom preference for resource scope + * + * @noextend This class is not intended to be extended by clients. + * @since 1.0 + */ +public class FileScopeProblemPreference extends AbstractProblemPreference { + /** + * Key for the scope preference + */ + public static final String KEY = "fileScope"; //$NON-NLS-1$ + /** + * Exclusion attribute + */ + public static final String EXCLUSION = "exclusion"; //$NON-NLS-1$ + /** + * Inclusion attribute + */ + public static final String INCLUSION = "inclusion"; //$NON-NLS-1$ + private IResource resource; + private IPath[] inclusion = new IPath[0]; + private IPath[] exclusion = new IPath[0]; + + /** + * Default constructor + */ + public FileScopeProblemPreference() { + setKey(KEY); + setLabel(Messages.FileScopeProblemPreference_Label); + } + + public PreferenceType getType() { + return PreferenceType.TYPE_CUSTOM; + } + + /** + * Get attribute. Possible keys are EXCUSION and INCLUSION + * + * @param key + * @return class attribute for given key + */ + public IPath[] getAttribute(String key) { + if (key == EXCLUSION) + return exclusion; + if (key == INCLUSION) + return inclusion; + return null; + } + + /** + * Set attribute to a value. Possible keys are EXCUSION and INCLUSION + * + * @param key + * @param value + */ + public void setAttribute(String key, IPath[] value) { + if (key == EXCLUSION) + exclusion = value.clone(); + if (key == INCLUSION) + inclusion = value.clone(); + } + + /** + * @return null for workspace, or project of the resource it is applicable + * for + */ + public IProject getProject() { + if (resource != null) + return resource.getProject(); + return null; + } + + /** + * @return path of the resource it is applicable to + */ + public IPath getPath() { + if (resource != null) + return resource.getFullPath(); + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + IWorkspaceRoot root = workspace.getRoot(); + return root.getFullPath(); + } + + /** + * @param resource + * the resource to set + */ + public void setResource(IResource resource) { + this.resource = resource; + } + + /** + * @return the resource for which scope is define. Null if workspace. + */ + public IResource getResource() { + return resource; + } + + public String exportValue() { + return exportPathList(INCLUSION, inclusion) + "," //$NON-NLS-1$ + + exportPathList(EXCLUSION, exclusion); + } + + protected String exportPathList(String key, IPath[] arr) { + String res = key + "=>("; //$NON-NLS-1$ + for (int i = 0; i < arr.length; i++) { + if (i != 0) + res += ","; //$NON-NLS-1$ + res += escape(arr[i].toPortableString()); + } + return res + ")"; //$NON-NLS-1$ + } + + @Override + public void importValue(StreamTokenizer tokenizer) throws IOException { + List inc = importPathList(tokenizer, INCLUSION); + inclusion = inc.toArray(new IPath[inc.size()]); + checkChar(tokenizer, ','); + List exc = importPathList(tokenizer, EXCLUSION); + exclusion = exc.toArray(new IPath[exc.size()]); + } + + private void checkChar(StreamTokenizer tokenizer, char c) + throws IOException { + tokenizer.nextToken(); + if (tokenizer.ttype != c) + throw new IllegalArgumentException("Expected " + c); //$NON-NLS-1$ + } + + private void checkKeyword(StreamTokenizer tokenizer, String keyword) + throws IOException { + tokenizer.nextToken(); + if (tokenizer.sval == null || !tokenizer.sval.equals(keyword)) + throw new IllegalArgumentException("Expected " + keyword); //$NON-NLS-1$ + } + + protected List importPathList(StreamTokenizer tokenizer, + String keyword) throws IOException { + checkKeyword(tokenizer, keyword); + checkChar(tokenizer, '='); + checkChar(tokenizer, '>'); + ArrayList list = new ArrayList(); + int token; + int index = 0; + try { + checkChar(tokenizer, '('); + token = tokenizer.nextToken(); + if (token != ')') + tokenizer.pushBack(); + else + return Collections.emptyList(); + while (true) { + token = tokenizer.nextToken(); + if (tokenizer.sval == null) + throw new IllegalArgumentException(); + list.add(new Path(tokenizer.sval)); + token = tokenizer.nextToken(); + if (token == ')') + break; + tokenizer.pushBack(); + checkChar(tokenizer, ','); + index++; + } + } catch (IOException e) { + throw new IllegalArgumentException(e); + } + return list; + } + + @Override + public Object getValue() { + return this; + } + + @Override + public void setValue(Object value) { + if (this == value) + return; + FileScopeProblemPreference scope = (FileScopeProblemPreference) value; + setAttribute(INCLUSION, scope.getAttribute(INCLUSION)); + setAttribute(EXCLUSION, scope.getAttribute(EXCLUSION)); + this.resource = scope.getResource(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.codan.core.param.AbstractProblemPreference#clone() + */ + @Override + public Object clone() { + FileScopeProblemPreference scope = (FileScopeProblemPreference) super + .clone(); + scope.setValue(this); + return scope; + } + + /** + * Checks that resource denotated by the given path is in scope (defined by + * exclusion/inclusion settings of this class). In inclusion list is defined + * check first if it belongs to it, returns false if not. + * Then checks if it belongs to exclusion list and return false if it is. + * + * @param path + * - resource path + * @return true is given path is in scope + */ + public boolean isInScope(IPath path) { + //System.err.println("test " + file + " " + exportValue()); + if (inclusion.length > 0) { + if (!matchesFilter(path, inclusion)) + return false; + } + if (exclusion.length > 0) { + if (matchesFilter(path, exclusion)) + return false; + } + return true; + } + + /** + * Checks that given path matches on the paths provided as second argument + * + * @param resourcePath - resource path + * @param paths - array of path patterns, for pattern see + * {@link CharOperation#pathMatch} + * @return true if matches with at least one pattern in the array + */ + public boolean matchesFilter(IPath resourcePath, IPath[] paths) { + char[] path = resourcePath.toString().toCharArray(); + for (int i = 0, length = paths.length; i < length; i++) { + char[] pattern = paths[i].toString().toCharArray(); + if (CharOperation.pathMatch(pattern, path, true, '/')) { + return true; + } + } + return false; + } +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/IProblemPreference.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/IProblemPreference.java new file mode 100644 index 0000000..6b0c316 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/IProblemPreference.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2009,2010 QNX Software Systems + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems (Alena Laskavaia) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.param; + +/** + * Problem preference. If problem has more than one it can be composite, i.e. + * map. Instead of implementing this interface clients must extend + * {@link AbstractProblemPreference} class. + * + * Problem Preference constist of preference metadata + * (IProblemPreferenceDescriptor) + * and value of preference (IProblemPreferenceValue). + * + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IProblemPreference extends Cloneable, IProblemPreferenceValue, + IProblemPreferenceDescriptor { +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/IProblemPreferenceCompositeDescriptor.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/IProblemPreferenceCompositeDescriptor.java new file mode 100644 index 0000000..392e0a2 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/IProblemPreferenceCompositeDescriptor.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2009,2010 QNX Software Systems + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems (Alena Laskavaia) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.param; + +/** + * Composite descriptor. For descriptors like map and list. + * + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IProblemPreferenceCompositeDescriptor { + /** + * Available if type is composite. Returns value of subdescriptor with the + * name of key. For the "list" type key is the number (index). + * + * @param key + * - name of the subdescriptor. + * @return child preference of the given key + */ + IProblemPreference getChildDescriptor(String key); + + /** + * Available for composite types. Returns array of children. + * + * @return array of children. 0 size of none. + */ + IProblemPreference[] getChildDescriptors(); + + /** + * Add preference + * + * @param preference + * @return added preference + */ + IProblemPreference addChildDescriptor(IProblemPreference preference); + + /** + * Remove preference + * + * @param preference + */ + void removeChildDescriptor(IProblemPreference preference); +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/IProblemPreferenceCompositeValue.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/IProblemPreferenceCompositeValue.java new file mode 100644 index 0000000..f44a659 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/IProblemPreferenceCompositeValue.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2009,2010 Alena Laskavaia + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.param; + +/** + * Interface for container type preferences, such as map or list + * + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IProblemPreferenceCompositeValue { + /** + * Returns value of the child element of a given key + * + * @param key + * @return value of the child preference + */ + Object getChildValue(String key); + + /** + * Sets the value of the child element of a given key + * + * @param key + * @param value + */ + void setChildValue(String key, Object value); + + /** + * Removes child element matching the given key + * + * @param key + */ + void removeChildValue(String key); +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/IProblemPreferenceDescriptor.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/IProblemPreferenceDescriptor.java new file mode 100644 index 0000000..f6f97e0 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/IProblemPreferenceDescriptor.java @@ -0,0 +1,171 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Alena Laskavaia + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.param; + +import java.io.File; +import java.util.List; +import java.util.Map; + +/** + * Problem parameter usually key=value settings that allows to alter checker + * behaviour for given problem. For example if checker finds violation of naming + * conventions for function, parameter would be the pattern of allowed names. + * + * IProblemPreferenceDescriptor represent preference's meta-info for the ui. If + * more than one parameter is required it can be map or list of sub-preferences. + * This is only needed for auto-generated ui for parameter + * editing. For more complex cases custom ui control should be used. Extend + * {@link AbstractProblemPreference} class + * to implement this interface. + * + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IProblemPreferenceDescriptor extends Cloneable { + /** + * Type of the user preference + */ + public enum PreferenceType { + /** + * String type, represented by string input field by default + */ + TYPE_STRING("string"), //$NON-NLS-1$ + /** + * Integer type, represented by integer input field by default + */ + TYPE_INTEGER("integer"), //$NON-NLS-1$ + /** + * Boolean type, represented by checkbox (boolean input field) + */ + TYPE_BOOLEAN("boolean"), //$NON-NLS-1$ + /** + * File type, represented by file picker input field + */ + TYPE_FILE("file"), //$NON-NLS-1$ + /** + * List type, represented by list (table) control + */ + TYPE_LIST("list"), //$NON-NLS-1$ + /** + * Map type, represented by composite of children fields + */ + TYPE_MAP("map"), //$NON-NLS-1$ + /** + * Custom type, represented by string input field by default + */ + TYPE_CUSTOM("custom"); //$NON-NLS-1$ + private String literal; + + private PreferenceType(String literal) { + this.literal = literal; + } + + /** + * @param name - name of the type literal (i.e. comes from name() or + * toString()) + * @return type represented by this name + */ + public static PreferenceType valueOfLiteral(String name) { + PreferenceType[] values = values(); + for (int i = 0; i < values.length; i++) { + PreferenceType e = values[i]; + if (e.literal.equals(name)) + return e; + } + return null; + } + + @Override + public String toString() { + return literal; + } + + /** + * @param value + * @return parameter type corresponding to the value java type + */ + public static PreferenceType typeOf(Object value) { + if (value instanceof Boolean) + return TYPE_BOOLEAN; + if (value instanceof String) + return TYPE_STRING; + if (value instanceof Integer) + return TYPE_INTEGER; + if (value instanceof File) + return TYPE_FILE; + if (value instanceof List) + return TYPE_LIST; + if (value instanceof Map) + return TYPE_MAP; + return TYPE_CUSTOM; + } + } + + /** + * Key of the preference. Key must be java-like identified or number. Cannot + * contain dots. Cannot be null. + * + * @return key + */ + String getKey(); + + /** + * type of the parameter, supports boolean, integer, string, file, list and + * map. For list type child preference can be + * accessed by number (index), if map is the type child preference can be + * accessed by a key (string) + * + * @return type of the preference + */ + PreferenceType getType(); + + /** + * Additional info on how it is represented in the ui, for example boolean + * can be represented as checkbox, drop-down and so on, Values TBD. + * Not supported at the moment. + * + * @return ui info or null if not set + */ + String getUiInfo(); + + /** + * User visible label for the parameter control in UI + * + * @return the label + */ + String getLabel(); + + /** + * Detailed explanation of parameter. Not supported at the moment. + * + * @return the toolTip text + */ + String getToolTip(); + + /** + * default clone implementation + * + * @return clone of the object + */ + Object clone(); + + /** + * @return parent preference + */ + IProblemPreference getParent(); + + /** + * Combined key of values from parents plus itself separated by dot + * + * @return qualified key + */ + String getQualifiedKey(); +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/IProblemPreferenceValue.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/IProblemPreferenceValue.java new file mode 100644 index 0000000..cbe9f4f --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/IProblemPreferenceValue.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2009,2010 QNX Software Systems + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems (Alena Laskavaia) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.param; + +/** + * Value of the problem preference. If more than one it can be composite, i.e. + * map.Extend {@link AbstractProblemPreference} class + * to implement this interface. + * + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface IProblemPreferenceValue extends Cloneable { + /** + * Get value of preference. + * + * @return object that represents the value. Limited number of object types + * are allowed. + * @see IProblemPreferenceDescriptor.PreferenceType + */ + Object getValue(); + + /** + * Set value of preference represented by this object. + * + * @param value + */ + void setValue(Object value); + + /** + * Export value in string representation required for storing in eclipse + * preferences. + * + * @return string representation of the value + */ + String exportValue(); + + /** + * Import value from string into internal object state. + * + * @param str + * - string from preferences, previously exported by exportValue + * method. + */ + void importValue(String str); +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/ListProblemPreference.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/ListProblemPreference.java new file mode 100644 index 0000000..333cb31 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/ListProblemPreference.java @@ -0,0 +1,323 @@ +/******************************************************************************* + * Copyright (c) 2009,2010 QNX Software Systems + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems (Alena Laskavaia) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.param; + +import java.io.IOException; +import java.io.StreamTokenizer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; + +/** + * List implementation of IProblemPreference. + * + * @noextend This class is not intended to be extended by clients. + */ +public class ListProblemPreference extends AbstractProblemPreference implements + IProblemPreferenceCompositeValue, IProblemPreferenceCompositeDescriptor { + /** + * Constant that represent a key for "shared" child preference (descriptor) + * of all elements + */ + public static final String COMMON_DESCRIPTOR_KEY = "#"; //$NON-NLS-1$ + protected ArrayList list = new ArrayList(); + protected IProblemPreference childDescriptor; + + /** + * @param key + * - key to access this preference + * @param label + * - label to be shown in UI + */ + public ListProblemPreference(String key, String label) { + setKey(key); + setLabel(label); + } + + public PreferenceType getType() { + return PreferenceType.TYPE_LIST; + } + + /** + * Set child descriptor (all elements have the same). Value and key + * of it would be ignored and reset. + * + * @param desc + * @return set child descriptor + */ + public IProblemPreference setChildDescriptor(IProblemPreference desc) { + childDescriptor = desc; + if (desc != null) { + childDescriptor.setValue(null); + ((AbstractProblemPreference) childDescriptor) + .setKey(COMMON_DESCRIPTOR_KEY); + } + return desc; + } + + /** + * Sets common descriptor for all elements, if value if not null sets the + * value for its key also. Do not make assumptions of values of desc after + * you pass it to this function. + * + * @return read only preference matching the key + */ + public IProblemPreference addChildDescriptor(IProblemPreference desc) { + Object value = desc.getValue(); + String key = desc.getKey(); + setChildDescriptor(desc); + setChildValue(key, value); + return getChildDescriptor(key); + } + + /** + * + * @return descriptor of the child elements + */ + public IProblemPreference getChildDescriptor() { + return childDescriptor; + } + + /** + * Returns cloned descriptor of the i'th child. Modifying return value would + * not affect internal state of the list element. + * + * @param i - index of the element + * @return child preference + */ + public IProblemPreference getChildDescriptor(int i) { + Object value = list.get(i); + AbstractProblemPreference desc = (AbstractProblemPreference) childDescriptor + .clone(); + desc.setKey(String.valueOf(i)); + desc.setValue(value); + return desc; + } + + /** + * Get read only problem preference for element equal to key's int value. + * If key is null or # return generic descriptor with null value. + * + * @throws NumberFormatException + * if key is not number + */ + public IProblemPreference getChildDescriptor(String key) + throws NumberFormatException { + if (key == null || key.equals(COMMON_DESCRIPTOR_KEY)) { + // return common descriptor + return getChildDescriptor(); + } + Integer iv = Integer.valueOf(key); + if (iv.intValue() >= list.size()) { + // create one + AbstractProblemPreference clone = (AbstractProblemPreference) childDescriptor + .clone(); + clone.setKey(key); + return clone; + } + return getChildDescriptor(iv.intValue()); + } + + /** + * Return array of clones values of child preferences. + */ + public IProblemPreference[] getChildDescriptors() { + IProblemPreference[] res = new IProblemPreference[list.size()]; + for (int i = 0; i < res.length; i++) { + res[i] = getChildDescriptor(i); + } + return res; + } + + public Object getChildValue(String key) { + int index = Integer.parseInt(key); + return getChildValue(index); + } + + /** + * @param index - index of the element + * @return child value by index + */ + public Object getChildValue(int index) { + return list.get(index); + } + + public void setChildValue(String key, Object value) { + int i = Integer.valueOf(key).intValue(); + setChildValue(i, value); + } + + /** + * @param i - index of the element + * @param value - value of the child element + */ + public void setChildValue(int i, Object value) { + if (value != null) { + while (i >= list.size()) { + list.add(null); + } + list.set(i, value); + } else { + while (i == list.size() - 1) { + list.remove(i); + } + } + } + + /** + * Adds value to the list + * + * @param value + */ + public void addChildValue(Object value) { + list.add(value); + } + + /** + * Removes child value by key + */ + public void removeChildValue(String key) { + int index = Integer.parseInt(key); + list.remove(index); + } + + @Override + public Object clone() { + ListProblemPreference list1 = (ListProblemPreference) super.clone(); + list1.list = new ArrayList(); + list1.setChildDescriptor((IProblemPreference) getChildDescriptor() + .clone()); + for (Iterator iterator = list.iterator(); iterator.hasNext();) { + Object value = iterator.next(); + list1.addChildValue(value); + } + return list1; + } + + public String exportValue() { + StringBuffer buf = new StringBuffer("("); //$NON-NLS-1$ + for (Iterator iterator = list.iterator(); iterator.hasNext();) { + IProblemPreference d = (IProblemPreference) childDescriptor.clone(); + d.setValue(iterator.next()); + buf.append(d.exportValue()); + if (iterator.hasNext()) + buf.append(","); //$NON-NLS-1$ + } + return buf.toString() + ")"; //$NON-NLS-1$ + } + + @Override + public void importValue(String str) { + StreamTokenizer tokenizer = getImportTokenizer(str); + try { + importValue(tokenizer); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException(str, e); + } + } + + @Override + public void importValue(StreamTokenizer tokenizer) { + clear(); + int token; + int index = 0; + try { + token = tokenizer.nextToken(); + String chara = String.valueOf((char) token); + if (token != '(') + throw new IllegalArgumentException(chara); + token = tokenizer.nextToken(); + if (token != ')') + tokenizer.pushBack(); + else + return; + while (true) { + String ik = String.valueOf(index); + IProblemPreference desc = getChildDescriptor(ik); + if (desc != null && desc instanceof AbstractProblemPreference) { + ((AbstractProblemPreference) desc).importValue(tokenizer); + setChildValue(ik, desc.getValue()); + } + token = tokenizer.nextToken(); + if (token == ')') + break; + if (token != ',') + throw new IllegalArgumentException(chara); + index++; + } + } catch (IOException e) { + throw new IllegalArgumentException(e); + } + } + + /** + * If info key is '#' resets common descriptor to null, otherwise removes + * value + */ + public void removeChildDescriptor(IProblemPreference info) { + if (info.getKey().equals(COMMON_DESCRIPTOR_KEY)) + setChildDescriptor(null); + else + removeChildValue(info.getKey()); + } + + /** + * @return children size + */ + public int size() { + return list.size(); + } + + /** + * Removes all values from the list + */ + public void clear() { + list.clear(); + } + + /** + * @return array of values of children elements. + */ + @Override + public Object getValue() { + return getValues(); + } + + /** + * Sets list value to values of array given as argument. + * + * @param value - must be Object[] + */ + @Override + public void setValue(Object value) { + Object[] values = (Object[]) value; + if (Arrays.deepEquals(getValues(), values)) { + return; + } + list.clear(); + for (int i = 0; i < values.length; i++) { + Object object = values[i]; + list.add(object); + } + } + + @Override + public String toString() { + return childDescriptor + ":" + list.toString(); //$NON-NLS-1$ + } + + /** + * @return array of values of children elements. + */ + public Object[] getValues() { + return list.toArray(new Object[list.size()]); + } +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/MapProblemPreference.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/MapProblemPreference.java new file mode 100644 index 0000000..6e865f0 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/MapProblemPreference.java @@ -0,0 +1,261 @@ +/******************************************************************************* + * Copyright (c) 2009,2010 QNX Software Systems + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX Software Systems (Alena Laskavaia) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.param; + +import java.io.IOException; +import java.io.StreamTokenizer; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.eclipse.cdt.codan.core.model.AbstractCheckerWithProblemPreferences; + +/** + * MapProblemPreference - for checker that needs more than one preferences and + * they all differently "named". + * For example checker for parameter names shadowing would have two boolean + * options: + * "check contructors" and + * "check setters". In this case you use this type. + * {@link AbstractCheckerWithProblemPreferences} class has map as default top + * level parameter preference. + * + * @noextend This class is not intended to be extended by clients. + */ +public class MapProblemPreference extends AbstractProblemPreference implements + IProblemPreferenceCompositeValue, IProblemPreferenceCompositeDescriptor { + protected LinkedHashMap hash = new LinkedHashMap(); + + /** + * Default constuctor + */ + public MapProblemPreference() { + super(); + } + + /** + * @param key + * - key for itself + * @param label + * - label for this group of parameters + */ + public MapProblemPreference(String key, String label) { + setKey(key); + setLabel(label); + } + + public PreferenceType getType() { + return PreferenceType.TYPE_MAP; + } + + /** + * Get parameter preference for element by key + * + */ + public IProblemPreference getChildDescriptor(String key) { + return hash.get(key); + } + + /** + * Adds or replaces child descriptor and value for the element with the key + * equals to desc.getKey(). The desc object would be put in the map, some of + * its field may be modified. + * + * @param desc + */ + public IProblemPreference addChildDescriptor(IProblemPreference desc) { + ((AbstractProblemPreference) desc).setParent(this); + hash.put(desc.getKey(), desc); + return desc; + } + + /** + * Return list of child descriptors. Client should threat returned value as + * read only, + * and not assume that modifying its elements would modify actual child + * values. + */ + public IProblemPreference[] getChildDescriptors() { + return hash.values().toArray( + new IProblemPreference[hash.values().size()]); + } + + /** + * Returns value of the child element by its key + */ + public Object getChildValue(String key) { + IProblemPreference childInfo = getChildDescriptor(key); + return childInfo.getValue(); + } + + /** + * Set child value by its key + */ + public void setChildValue(String key, Object value) { + IProblemPreference pref = getChildDescriptor(key); + if (pref == null) + throw new IllegalArgumentException("Preference for " + key //$NON-NLS-1$ + + " must exists before setting its value"); //$NON-NLS-1$ + pref.setValue(value); + hash.put(key, pref); // cannot assume getChildDescriptor returns shared value + } + + /** + * Removes child value and descriptor by key + */ + public void removeChildValue(String key) { + hash.remove(key); + } + + @Override + public Object clone() { + MapProblemPreference map = (MapProblemPreference) super.clone(); + map.hash = new LinkedHashMap(); + for (Iterator iterator = hash.keySet().iterator(); iterator + .hasNext();) { + String key = iterator.next(); + map.hash.put(key, (IProblemPreference) hash.get(key).clone()); + } + return map; + } + + public String exportValue() { + StringBuffer buf = new StringBuffer("{"); //$NON-NLS-1$ + for (Iterator iterator = hash.keySet().iterator(); iterator + .hasNext();) { + String key = iterator.next(); + IProblemPreference d = hash.get(key); + buf.append(key + "=>" + d.exportValue()); //$NON-NLS-1$ + if (iterator.hasNext()) + buf.append(","); //$NON-NLS-1$ + } + return buf.toString() + "}"; //$NON-NLS-1$ + } + + @Override + public void importValue(String str) { + StreamTokenizer tokenizer = getImportTokenizer(str); + try { + importValue(tokenizer); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException(str + ":" + e.toString(), e); //$NON-NLS-1$ + } + } + + /** + * @param tokenizer + */ + @Override + public void importValue(StreamTokenizer tokenizer) { + int token; + try { + token = tokenizer.nextToken(); + String chara = String.valueOf((char) token); + if (token != '{') { + throw new IllegalArgumentException(chara); + } + while (true) { + token = tokenizer.nextToken(); + String key = tokenizer.sval; + token = tokenizer.nextToken(); + if (token != '=') + throw new IllegalArgumentException(chara); + token = tokenizer.nextToken(); + if (token != '>') + throw new IllegalArgumentException(chara); + IProblemPreference desc = getChildDescriptor(key); + if (desc != null && desc instanceof AbstractProblemPreference) { + ((AbstractProblemPreference) desc).importValue(tokenizer); + setChildValue(key, desc.getValue()); + } + token = tokenizer.nextToken(); + if (token == '}') + break; + if (token != ',') + throw new IllegalArgumentException(chara); + } + } catch (IOException e) { + throw new IllegalArgumentException(e); + } + } + + /** + * Removes child descriptor by its key + */ + public void removeChildDescriptor(IProblemPreference info) { + hash.remove(info.getKey()); + } + + /** + * @return size of the map + */ + public int size() { + return hash.size(); + } + + /** + * Clears the map + */ + public void clear() { + hash.clear(); + } + + @Override + public String toString() { + return hash.values().toString(); + } + + /** + * Value of this preference is a map key=>value of child preferences. + * Modifying this returned map would not change internal state of this + * object. + */ + @Override + public Object getValue() { + LinkedHashMap map = new LinkedHashMap(); + for (Iterator iterator = hash.values().iterator(); iterator + .hasNext();) { + IProblemPreference pref = iterator.next(); + map.put(pref.getKey(), pref.getValue()); + } + return map; + } + + /** + * Set values for this object child elements. Elements are not present in + * this map would be removed. + * Preference descriptors for the keys must be set before calling this + * method, unless value if instanceof {@link IProblemPreference}. + * + * @param value - must be Map + */ + @SuppressWarnings("unchecked") + @Override + public void setValue(Object value) { + Map map = (Map) value; + LinkedHashMap hash2 = (LinkedHashMap) hash + .clone(); + hash.clear(); + for (Iterator iterator = map.keySet().iterator(); iterator + .hasNext();) { + String key = iterator.next(); + Object value2 = map.get(key); + if (value2 instanceof IProblemPreference) { + hash.put(key, (IProblemPreference) value2); + } else { + setChildValue(key, value2); + IProblemPreference pref = hash2.get(key); + pref.setValue(value2); + hash.put(key, pref); + } + } + } +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/CVS/Tag b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/CVS/Tag new file mode 100644 index 0000000..3cd1ca4 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/CVS/Tag @@ -0,0 +1 @@ +TCDT_7_0_0 diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CVS/Entries b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CVS/Entries index 49bf43c..9771946 100644 --- a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CVS/Entries +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CVS/Entries @@ -1,5 +1,8 @@ -/CheckersRegisry.java/1.3/Wed Dec 16 21:48:48 2009// -/CodanBuilder.java/1.3/Wed Dec 16 21:48:48 2009// -/CodanPreferencesLoader.java/1.1/Wed Sep 23 23:29:36 2009// -/CodeAnlysisNature.java/1.1/Sat Aug 22 21:16:49 2009// +/CharOperation.java/1.2/Thu Jun 3 17:01:53 2010//TCDT_7_0_0 +/CheckersRegistry.java/1.3/Thu Jun 3 17:01:53 2010//TCDT_7_0_0 +/CodanApplication.java/1.7/Sun Jun 27 01:30:42 2010//TCDT_7_0_0 +/CodanBuilder.java/1.12/Sun Jun 27 01:30:42 2010//TCDT_7_0_0 +/CodanPreferencesLoader.java/1.8/Sun Jun 27 01:30:42 2010//TCDT_7_0_0 +/CodeAnlysisNature.java/1.4/Sun Jun 27 01:30:42 2010//TCDT_7_0_0 +D/cfg//// D/model//// diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CVS/Tag b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CVS/Tag new file mode 100644 index 0000000..49a449a --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CVS/Tag @@ -0,0 +1 @@ +NCDT_7_0_0 diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CharOperation.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CharOperation.java new file mode 100644 index 0000000..7790814 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CharOperation.java @@ -0,0 +1,2713 @@ +/******************************************************************************* + * Copyright (c) 2010 Alena Laskavaia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.internal.core; + +/** + * This class is a collection of helper methods to manipulate char arrays. + * + * @since 2.1 + */ +public final class CharOperation { + /** + * Constant for an empty char array + */ + public static final char[] NO_CHAR = new char[0]; + /** + * Constant for an empty char array with two dimensions. + */ + public static final char[][] NO_CHAR_CHAR = new char[0][]; + + /** + * Answers a new array with appending the suffix character at the end of the + * array. + *
    + *
    + * For example:
    + *
      + *
    1. +	 * array = { 'a', 'b' }
      +	 * suffix = 'c'
      +	 * => result = { 'a', 'b' , 'c' }
      +	 * 
      + *
    2. + *
    3. +	 * array = null
      +	 * suffix = 'c'
      +	 * => result = { 'c' }
      +	 * 
    4. + *
    + * + * @param array + * the array that is concanated with the suffix character + * @param suffix + * the suffix character + * @return the new array + */ + public static final char[] append(char[] array, char suffix) { + if (array == null) + return new char[] { suffix }; + int length = array.length; + System.arraycopy(array, 0, array = new char[length + 1], 0, length); + array[length] = suffix; + return array; + } + + /** + * Append the given subarray to the target array starting at the given index + * in the target array. + * The start of the subarray is inclusive, the end is exclusive. + * Answers a new target array if it needs to grow, otherwise answers the + * same target array. + *
    + * For example:
    + *
      + *
    1. +	 * target = { 'a', 'b', '0' }
      +	 * index = 2
      +	 * array = { 'c', 'd' }
      +	 * start = 0
      +	 * end = 1
      +	 * => result = { 'a', 'b' , 'c' }
      +	 * 
      + *
    2. + *
    3. +	 * target = { 'a', 'b' }
      +	 * index = 2
      +	 * array = { 'c', 'd' }
      +	 * start = 0
      +	 * end = 1
      +	 * => result = { 'a', 'b' , 'c', '0', '0' , '0' } (new array)
      +	 * 
    4. + *
    5. +	 * target = { 'a', 'b', 'c' }
      +	 * index = 1
      +	 * array = { 'c', 'd', 'e', 'f' }
      +	 * start = 1
      +	 * end = 4
      +	 * => result = { 'a', 'd' , 'e', 'f', '0', '0', '0', '0' } (new array)
      +	 * 
    6. + *
    + * + * @param target + * the given target + * @param index + * the given index + * @param array + * the given array + * @param start + * the given start index + * @param end + * the given end index + * + * @return the new array + * @throws NullPointerException + * if the target array is null + */ + public static final char[] append(char[] target, int index, char[] array, + int start, int end) { + int targetLength = target.length; + int subLength = end - start; + int newTargetLength = subLength + index; + if (newTargetLength > targetLength) { + System.arraycopy(target, 0, target = new char[newTargetLength * 2], + 0, index); + } + System.arraycopy(array, start, target, index, subLength); + return target; + } + + /** + * Answers the concatenation of the two arrays. It answers null if the two + * arrays are null. + * If the first array is null, then the second array is returned. + * If the second array is null, then the first array is returned. + *
    + *
    + * For example: + *
      + *
    1. +	 * first = null
      +	 * second = null
      +	 * => result = null
      +	 * 
      + *
    2. + *
    3. +	 * first = { { ' a' } }
      +	 * second = null
      +	 * => result = { { ' a' } }
      +	 * 
      + *
    4. + *
    5. +	 * first = null
      +	 * second = { { ' a' } }
      +	 * => result = { { ' a' } }
      +	 * 
      + *
    6. + *
    7. +	 * first = { { ' b' } }
      +	 * second = { { ' a' } }
      +	 * => result = { { ' b' }, { ' a' } }
      +	 * 
      + *
    8. + *
    + * + * @param first + * the first array to concatenate + * @param second + * the second array to concatenate + * @return the concatenation of the two arrays, or null if the two arrays + * are null. + */ + public static final char[][] arrayConcat(char[][] first, char[][] second) { + if (first == null) + return second; + if (second == null) + return first; + int length1 = first.length; + int length2 = second.length; + char[][] result = new char[length1 + length2][]; + System.arraycopy(first, 0, result, 0, length1); + System.arraycopy(second, 0, result, length1, length2); + return result; + } + + /** + * Answers a new array adding the second array at the end of first array. + * It answers null if the first and second are null. + * If the first array is null, then a new array char[][] is created with + * second. + * If the second array is null, then the first array is returned. + *
    + *
    + * For example: + *
      + *
    1. +	 * first = null
      +	 * second = { 'a' }
      +	 * => result = { { ' a' } }
      +	 * 
      + *
    2. +	 * first = { { ' a' } }
      +	 * second = null
      +	 * => result = { { ' a' } }
      +	 * 
      + *
    3. + *
    4. +	 * first = { { ' a' } }
      +	 * second = { ' b' }
      +	 * => result = { { ' a' } , { ' b' } }
      +	 * 
      + *
    5. + *
    + * + * @param first + * the first array to concatenate + * @param second + * the array to add at the end of the first array + * @return a new array adding the second array at the end of first array, or + * null if the two arrays are null. + */ + public static final char[][] arrayConcat(char[][] first, char[] second) { + if (second == null) + return first; + if (first == null) + return new char[][] { second }; + int length = first.length; + char[][] result = new char[length + 1][]; + System.arraycopy(first, 0, result, 0, length); + result[length] = second; + return result; + } + + /** + * Compares the contents of the two arrays array and prefix. Returns + *
      + *
    • zero if the array starts with the prefix contents
    • + *
    • the difference between the first two characters that are not equal + *
    • + *
    • one if array length is lower than the prefix length and that the + * prefix starts with the + * array contents.
    • + *
    + *

    + * For example: + *

      + *
    1. +	 * array = null
      +	 * prefix = null
      +	 * => result = NullPointerException
      +	 * 
      + *
    2. + *
    3. +	 * array = { 'a', 'b', 'c', 'd', 'e' }
      +	 * prefix = { 'a', 'b', 'c'}
      +	 * => result = 0
      +	 * 
      + *
    4. + *
    5. +	 * array = { 'a', 'b', 'c', 'd', 'e' }
      +	 * prefix = { 'a', 'B', 'c'}
      +	 * => result = 32
      +	 * 
      + *
    6. + *
    7. +	 * array = { 'd', 'b', 'c', 'd', 'e' }
      +	 * prefix = { 'a', 'b', 'c'}
      +	 * => result = 3
      +	 * 
      + *
    8. + *
    9. +	 * array = { 'a', 'b', 'c', 'd', 'e' }
      +	 * prefix = { 'd', 'b', 'c'}
      +	 * => result = -3
      +	 * 
      + *
    10. + *
    11. +	 * array = { 'a', 'a', 'c', 'd', 'e' }
      +	 * prefix = { 'a', 'e', 'c'}
      +	 * => result = -4
      +	 * 
      + *
    12. + *
    + *

    + * + * @param array + * the given array + * @param prefix + * the given prefix + * @return the result of the comparison + * @exception NullPointerException + * if either array or prefix is null + */ + public static final int compareWith(char[] array, char[] prefix) { + int arrayLength = array.length; + int prefixLength = prefix.length; + int min = Math.min(arrayLength, prefixLength); + int i = 0; + while (min-- != 0) { + char c1 = array[i]; + char c2 = prefix[i++]; + if (c1 != c2) + return c1 - c2; + } + if (prefixLength == i) + return 0; + return 1; + } + + /** + * Answers the concatenation of the two arrays. It answers null if the two + * arrays are null. + * If the first array is null, then the second array is returned. + * If the second array is null, then the first array is returned. + *
    + *
    + * For example: + *
      + *
    1. +	 * first = null
      +	 * second = { 'a' }
      +	 * => result = { ' a' }
      +	 * 
      + *
    2. + *
    3. +	 * first = { ' a' }
      +	 * second = null
      +	 * => result = { ' a' }
      +	 * 
      + *
    4. + *
    5. +	 * first = { ' a' }
      +	 * second = { ' b' }
      +	 * => result = { ' a' , ' b' }
      +	 * 
      + *
    6. + *
    + * + * @param first + * the first array to concatenate + * @param second + * the second array to concatenate + * @return the concatenation of the two arrays, or null if the two arrays + * are null. + */ + public static final char[] concat(char[] first, char[] second) { + if (first == null) + return second; + if (second == null) + return first; + int length1 = first.length; + int length2 = second.length; + char[] result = new char[length1 + length2]; + System.arraycopy(first, 0, result, 0, length1); + System.arraycopy(second, 0, result, length1, length2); + return result; + } + + /** + * Answers the concatenation of the three arrays. It answers null if the + * three arrays are null. + * If first is null, it answers the concatenation of second and third. + * If second is null, it answers the concatenation of first and third. + * If third is null, it answers the concatenation of first and second. + *
    + *
    + * For example: + *
      + *
    1. +	 * first = null
      +	 * second = { 'a' }
      +	 * third = { 'b' }
      +	 * => result = { ' a', 'b' }
      +	 * 
      + *
    2. + *
    3. +	 * first = { 'a' }
      +	 * second = null
      +	 * third = { 'b' }
      +	 * => result = { ' a', 'b' }
      +	 * 
      + *
    4. + *
    5. +	 * first = { 'a' }
      +	 * second = { 'b' }
      +	 * third = null
      +	 * => result = { ' a', 'b' }
      +	 * 
      + *
    6. + *
    7. +	 * first = null
      +	 * second = null
      +	 * third = null
      +	 * => result = null
      +	 * 
      + *
    8. + *
    9. +	 * first = { 'a' }
      +	 * second = { 'b' }
      +	 * third = { 'c' }
      +	 * => result = { 'a', 'b', 'c' }
      +	 * 
      + *
    10. + *
    + * + * @param first + * the first array to concatenate + * @param second + * the second array to concatenate + * @param third + * the third array to concatenate + * + * @return the concatenation of the three arrays, or null if the three + * arrays are null. + */ + public static final char[] concat(char[] first, char[] second, char[] third) { + if (first == null) + return concat(second, third); + if (second == null) + return concat(first, third); + if (third == null) + return concat(first, second); + int length1 = first.length; + int length2 = second.length; + int length3 = third.length; + char[] result = new char[length1 + length2 + length3]; + System.arraycopy(first, 0, result, 0, length1); + System.arraycopy(second, 0, result, length1, length2); + System.arraycopy(third, 0, result, length1 + length2, length3); + return result; + } + + /** + * Answers the concatenation of the two arrays inserting the separator + * character between the two arrays. + * It answers null if the two arrays are null. + * If the first array is null, then the second array is returned. + * If the second array is null, then the first array is returned. + *
    + *
    + * For example: + *
      + *
    1. +	 * first = null
      +	 * second = { 'a' }
      +	 * separator = '/'
      +	 * => result = { ' a' }
      +	 * 
      + *
    2. + *
    3. +	 * first = { ' a' }
      +	 * second = null
      +	 * separator = '/'
      +	 * => result = { ' a' }
      +	 * 
      + *
    4. + *
    5. +	 * first = { ' a' }
      +	 * second = { ' b' }
      +	 * separator = '/'
      +	 * => result = { ' a' , '/', 'b' }
      +	 * 
      + *
    6. + *
    + * + * @param first + * the first array to concatenate + * @param second + * the second array to concatenate + * @param separator + * the character to insert + * @return the concatenation of the two arrays inserting the separator + * character + * between the two arrays , or null if the two arrays are null. + */ + public static final char[] concat(char[] first, char[] second, + char separator) { + if (first == null) + return second; + if (second == null) + return first; + int length1 = first.length; + if (length1 == 0) + return second; + int length2 = second.length; + if (length2 == 0) + return first; + char[] result = new char[length1 + length2 + 1]; + System.arraycopy(first, 0, result, 0, length1); + result[length1] = separator; + System.arraycopy(second, 0, result, length1 + 1, length2); + return result; + } + + /** + * Answers the concatenation of the three arrays inserting the sep1 + * character between the + * two arrays and sep2 between the last two. + * It answers null if the three arrays are null. + * If the first array is null, then it answers the concatenation of second + * and third inserting + * the sep2 character between them. + * If the second array is null, then it answers the concatenation of first + * and third inserting + * the sep1 character between them. + * If the third array is null, then it answers the concatenation of first + * and second inserting + * the sep1 character between them. + *
    + *
    + * For example: + *
      + *
    1. +	 * first = null
      +	 * sep1 = '/'
      +	 * second = { 'a' }
      +	 * sep2 = ':'
      +	 * third = { 'b' }
      +	 * => result = { ' a' , ':', 'b' }
      +	 * 
      + *
    2. + *
    3. +	 * first = { 'a' }
      +	 * sep1 = '/'
      +	 * second = null
      +	 * sep2 = ':'
      +	 * third = { 'b' }
      +	 * => result = { ' a' , '/', 'b' }
      +	 * 
      + *
    4. + *
    5. +	 * first = { 'a' }
      +	 * sep1 = '/'
      +	 * second = { 'b' }
      +	 * sep2 = ':'
      +	 * third = null
      +	 * => result = { ' a' , '/', 'b' }
      +	 * 
      + *
    6. + *
    7. +	 * first = { 'a' }
      +	 * sep1 = '/'
      +	 * second = { 'b' }
      +	 * sep2 = ':'
      +	 * third = { 'c' }
      +	 * => result = { ' a' , '/', 'b' , ':', 'c' }
      +	 * 
      + *
    8. + *
    + * + * @param first + * the first array to concatenate + * @param sep1 + * the character to insert + * @param second + * the second array to concatenate + * @param sep2 + * the character to insert + * @param third + * the second array to concatenate + * @return the concatenation of the three arrays inserting the sep1 + * character between the + * two arrays and sep2 between the last two. + */ + public static final char[] concat(char[] first, char sep1, char[] second, + char sep2, char[] third) { + if (first == null) + return concat(second, third, sep2); + if (second == null) + return concat(first, third, sep1); + if (third == null) + return concat(first, second, sep1); + int length1 = first.length; + int length2 = second.length; + int length3 = third.length; + char[] result = new char[length1 + length2 + length3 + 2]; + System.arraycopy(first, 0, result, 0, length1); + result[length1] = sep1; + System.arraycopy(second, 0, result, length1 + 1, length2); + result[length1 + length2 + 1] = sep2; + System.arraycopy(third, 0, result, length1 + length2 + 2, length3); + return result; + } + + /** + * Answers a new array with prepending the prefix character and appending + * the suffix + * character at the end of the array. If array is null, it answers a new + * array containing the + * prefix and the suffix characters. + *
    + *
    + * For example:
    + *
      + *
    1. +	 * prefix = 'a'
      +	 * array = { 'b' }
      +	 * suffix = 'c'
      +	 * => result = { 'a', 'b' , 'c' }
      +	 * 
      + *
    2. + *
    3. +	 * prefix = 'a'
      +	 * array = null
      +	 * suffix = 'c'
      +	 * => result = { 'a', 'c' }
      +	 * 
    4. + *
    + * + * @param prefix + * the prefix character + * @param array + * the array that is concanated with the prefix and suffix + * characters + * @param suffix + * the suffix character + * @return the new array + */ + public static final char[] concat(char prefix, char[] array, char suffix) { + if (array == null) + return new char[] { prefix, suffix }; + int length = array.length; + char[] result = new char[length + 2]; + result[0] = prefix; + System.arraycopy(array, 0, result, 1, length); + result[length + 1] = suffix; + return result; + } + + /** + * Answers the concatenation of the given array parts using the given + * separator between each + * part and appending the given name at the end. + *
    + *
    + * For example:
    + *
      + *
    1. +	 * name = { 'c' }
      +	 * array = { { 'a' }, { 'b' } }
      +	 * separator = '.'
      +	 * => result = { 'a', '.', 'b' , '.', 'c' }
      +	 * 
      + *
    2. + *
    3. +	 * name = null
      +	 * array = { { 'a' }, { 'b' } }
      +	 * separator = '.'
      +	 * => result = { 'a', '.', 'b' }
      +	 * 
    4. + *
    5. +	 * name = { ' c' }
      +	 * array = null
      +	 * separator = '.'
      +	 * => result = { 'c' }
      +	 * 
    6. + *
    + * + * @param name + * the given name + * @param array + * the given array + * @param separator + * the given separator + * @return the concatenation of the given array parts using the given + * separator between each + * part and appending the given name at the end + */ + public static final char[] concatWith(char[] name, char[][] array, + char separator) { + int nameLength = name == null ? 0 : name.length; + if (nameLength == 0) + return concatWith(array, separator); + if (array == null) + return name; + final int length = array.length; + if (length == 0) + return name; + int size = nameLength; + int index = length; + while (--index >= 0) + if (array[index].length > 0) + size += array[index].length + 1; + char[] result = new char[size]; + index = size; + for (int i = length - 1; i >= 0; i--) { + int subLength = array[i].length; + if (subLength > 0) { + index -= subLength; + System.arraycopy(array[i], 0, result, index, subLength); + result[--index] = separator; + } + } + System.arraycopy(name, 0, result, 0, nameLength); + return result; + } + + /** + * Answers the concatenation of the given array parts using the given + * separator between each + * part and appending the given name at the end. + *
    + *
    + * For example:
    + *
      + *
    1. +	 * name = { 'c' }
      +	 * array = { { 'a' }, { 'b' } }
      +	 * separator = '.'
      +	 * => result = { 'a', '.', 'b' , '.', 'c' }
      +	 * 
      + *
    2. + *
    3. +	 * name = null
      +	 * array = { { 'a' }, { 'b' } }
      +	 * separator = '.'
      +	 * => result = { 'a', '.', 'b' }
      +	 * 
    4. + *
    5. +	 * name = { ' c' }
      +	 * array = null
      +	 * separator = '.'
      +	 * => result = { 'c' }
      +	 * 
    6. + *
    + * + * @param array + * the given array + * @param name + * the given name + * @param separator + * the given separator + * @return the concatenation of the given array parts using the given + * separator between each + * part and appending the given name at the end + */ + public static final char[] concatWith(char[][] array, char[] name, + char separator) { + int nameLength = name == null ? 0 : name.length; + if (nameLength == 0) + return concatWith(array, separator); + if (array == null) + return name; + final int length = array.length; + if (length == 0) + return name; + int size = nameLength; + int index = length; + while (--index >= 0) + if (array[index].length > 0) + size += array[index].length + 1; + char[] result = new char[size]; + index = 0; + for (int i = 0; i < length; i++) { + int subLength = array[i].length; + if (subLength > 0) { + System.arraycopy(array[i], 0, result, index, subLength); + index += subLength; + result[index++] = separator; + } + } + System.arraycopy(name, 0, result, index, nameLength); + return result; + } + + /** + * Answers the concatenation of the given array parts using the given + * separator between each part. + *
    + *
    + * For example:
    + *
      + *
    1. +	 * array = { { 'a' }, { 'b' } }
      +	 * separator = '.'
      +	 * => result = { 'a', '.', 'b' }
      +	 * 
      + *
    2. + *
    3. +	 * array = null
      +	 * separator = '.'
      +	 * => result = { }
      +	 * 
    4. + *
    + * + * @param array + * the given array + * @param separator + * the given separator + * @return the concatenation of the given array parts using the given + * separator between each part + */ + public static final char[] concatWith(char[][] array, char separator) { + if (array == null) + return CharOperation.NO_CHAR; + int length = array.length; + if (length == 0) + return CharOperation.NO_CHAR; + int size = length - 1; + int index = length; + while (--index >= 0) { + if (array[index].length == 0) + size--; + else + size += array[index].length; + } + if (size <= 0) + return CharOperation.NO_CHAR; + char[] result = new char[size]; + index = length; + while (--index >= 0) { + length = array[index].length; + if (length > 0) { + System.arraycopy(array[index], 0, result, (size -= length), + length); + if (--size >= 0) + result[size] = separator; + } + } + return result; + } + + /** + * Answers true if the array contains an occurrence of character, false + * otherwise. + * + *
    + *
    + * For example: + *
      + *
    1. +	 * character = 'c'
      +	 * array = { { ' a' }, { ' b' } }
      +	 * result => false
      +	 * 
      + *
    2. + *
    3. +	 * character = 'a'
      +	 * array = { { ' a' }, { ' b' } }
      +	 * result => true
      +	 * 
      + *
    4. + *
    + * + * @param character + * the character to search + * @param array + * the array in which the search is done + * @return true if the array contains an occurrence of character, false + * otherwise. + * @exception NullPointerException + * if array is null. + */ + public static final boolean contains(char character, char[][] array) { + for (int i = array.length; --i >= 0;) { + char[] subarray = array[i]; + for (int j = subarray.length; --j >= 0;) + if (subarray[j] == character) + return true; + } + return false; + } + + /** + * Answers true if the array contains an occurrence of character, false + * otherwise. + * + *
    + *
    + * For example: + *
      + *
    1. +	 * character = 'c'
      +	 * array = { ' b' }
      +	 * result => false
      +	 * 
      + *
    2. + *
    3. +	 * character = 'a'
      +	 * array = { ' a' , ' b' }
      +	 * result => true
      +	 * 
      + *
    4. + *
    + * + * @param character + * the character to search + * @param array + * the array in which the search is done + * @return true if the array contains an occurrence of character, false + * otherwise. + * @exception NullPointerException + * if array is null. + */ + public static final boolean contains(char character, char[] array) { + for (int i = array.length; --i >= 0;) + if (array[i] == character) + return true; + return false; + } + + /** + * Answers a deep copy of the toCopy array. + * + * @param toCopy + * the array to copy + * @return a deep copy of the toCopy array. + */ + public static final char[][] deepCopy(char[][] toCopy) { + int toCopyLength = toCopy.length; + char[][] result = new char[toCopyLength][]; + for (int i = 0; i < toCopyLength; i++) { + char[] toElement = toCopy[i]; + int toElementLength = toElement.length; + char[] resultElement = new char[toElementLength]; + System.arraycopy(toElement, 0, resultElement, 0, toElementLength); + result[i] = resultElement; + } + return result; + } + + /** + * Return true if array ends with the sequence of characters contained in + * toBeFound, + * otherwise false. + *
    + *
    + * For example: + *
      + *
    1. +	 * array = { 'a', 'b', 'c', 'd' }
      +	 * toBeFound = { 'b', 'c' }
      +	 * result => false
      +	 * 
      + *
    2. + *
    3. +	 * array = { 'a', 'b', 'c' }
      +	 * toBeFound = { 'b', 'c' }
      +	 * result => true
      +	 * 
      + *
    4. + *
    + * + * @param array + * the array to check + * @param toBeFound + * the array to find + * @return true if array ends with the sequence of characters contained in + * toBeFound, + * otherwise false. + * @exception NullPointerException + * if array is null or toBeFound is null + */ + public static final boolean endsWith(char[] array, char[] toBeFound) { + int i = toBeFound.length; + int j = array.length - i; + if (j < 0) + return false; + while (--i >= 0) + if (toBeFound[i] != array[i + j]) + return false; + return true; + } + + /** + * Answers true if the two arrays are identical character by character, + * otherwise false. + * The equality is case sensitive. + *
    + *
    + * For example: + *
      + *
    1. +	 * first = null
      +	 * second = null
      +	 * result => true
      +	 * 
      + *
    2. + *
    3. +	 * first = { { } }
      +	 * second = null
      +	 * result => false
      +	 * 
      + *
    4. + *
    5. +	 * first = { { 'a' } }
      +	 * second = { { 'a' } }
      +	 * result => true
      +	 * 
      + *
    6. + *
    7. +	 * first = { { 'A' } }
      +	 * second = { { 'a' } }
      +	 * result => false
      +	 * 
      + *
    8. + *
    + * + * @param first + * the first array + * @param second + * the second array + * @return true if the two arrays are identical character by character, + * otherwise false + */ + public static final boolean equals(char[][] first, char[][] second) { + if (first == second) + return true; + if (first == null || second == null) + return false; + if (first.length != second.length) + return false; + for (int i = first.length; --i >= 0;) + if (!equals(first[i], second[i])) + return false; + return true; + } + + /** + * If isCaseSensite is true, answers true if the two arrays are identical + * character + * by character, otherwise false. + * If it is false, answers true if the two arrays are identical character by + * character without checking the case, otherwise false. + *
    + *
    + * For example: + *
      + *
    1. +	 * first = null
      +	 * second = null
      +	 * isCaseSensitive = true
      +	 * result => true
      +	 * 
      + *
    2. + *
    3. +	 * first = { { } }
      +	 * second = null
      +	 * isCaseSensitive = true
      +	 * result => false
      +	 * 
      + *
    4. + *
    5. +	 * first = { { 'A' } }
      +	 * second = { { 'a' } }
      +	 * isCaseSensitive = true
      +	 * result => false
      +	 * 
      + *
    6. + *
    7. +	 * first = { { 'A' } }
      +	 * second = { { 'a' } }
      +	 * isCaseSensitive = false
      +	 * result => true
      +	 * 
      + *
    8. + *
    + * + * @param first + * the first array + * @param second + * the second array + * @param isCaseSensitive + * check whether or not the equality should be case sensitive + * @return true if the two arrays are identical character by character + * according to the value + * of isCaseSensitive, otherwise false + */ + public static final boolean equals(char[][] first, char[][] second, + boolean isCaseSensitive) { + if (isCaseSensitive) { + return equals(first, second); + } + if (first == second) + return true; + if (first == null || second == null) + return false; + if (first.length != second.length) + return false; + for (int i = first.length; --i >= 0;) + if (!equals(first[i], second[i], false)) + return false; + return true; + } + + /** + * Answers true if the two arrays are identical character by character, + * otherwise false. + * The equality is case sensitive. + *
    + *
    + * For example: + *
      + *
    1. +	 * first = null
      +	 * second = null
      +	 * result => true
      +	 * 
      + *
    2. + *
    3. +	 * first = { }
      +	 * second = null
      +	 * result => false
      +	 * 
      + *
    4. + *
    5. +	 * first = { 'a' }
      +	 * second = { 'a' }
      +	 * result => true
      +	 * 
      + *
    6. + *
    7. +	 * first = { 'a' }
      +	 * second = { 'A' }
      +	 * result => false
      +	 * 
      + *
    8. + *
    + * + * @param first + * the first array + * @param second + * the second array + * @return true if the two arrays are identical character by character, + * otherwise false + */ + public static final boolean equals(char[] first, char[] second) { + if (first == second) + return true; + if (first == null || second == null) + return false; + if (first.length != second.length) + return false; + for (int i = first.length; --i >= 0;) + if (first[i] != second[i]) + return false; + return true; + } + + /** + * If isCaseSensite is true, answers true if the two arrays are identical + * character + * by character, otherwise false. + * If it is false, answers true if the two arrays are identical character by + * character without checking the case, otherwise false. + *
    + *
    + * For example: + *
      + *
    1. +	 * first = null
      +	 * second = null
      +	 * isCaseSensitive = true
      +	 * result => true
      +	 * 
      + *
    2. + *
    3. +	 * first = { }
      +	 * second = null
      +	 * isCaseSensitive = true
      +	 * result => false
      +	 * 
      + *
    4. + *
    5. +	 * first = { 'A' }
      +	 * second = { 'a' }
      +	 * isCaseSensitive = true
      +	 * result => false
      +	 * 
      + *
    6. + *
    7. +	 * first = { 'A' }
      +	 * second = { 'a' }
      +	 * isCaseSensitive = false
      +	 * result => true
      +	 * 
      + *
    8. + *
    + * + * @param first + * the first array + * @param second + * the second array + * @param isCaseSensitive + * check whether or not the equality should be case sensitive + * @return true if the two arrays are identical character by character + * according to the value + * of isCaseSensitive, otherwise false + */ + public static final boolean equals(char[] first, char[] second, + boolean isCaseSensitive) { + if (isCaseSensitive) { + return equals(first, second); + } + if (first == second) + return true; + if (first == null || second == null) + return false; + if (first.length != second.length) + return false; + for (int i = first.length; --i >= 0;) + if (Character.toLowerCase(first[i]) != Character + .toLowerCase(second[i])) + return false; + return true; + } + + /** + * If isCaseSensite is true, the equality is case sensitive, otherwise it is + * case insensitive. + * + * Answers true if the name contains the fragment at the starting index + * startIndex, otherwise false. + *
    + *
    + * For example: + *
      + *
    1. +	 * fragment = { 'b', 'c' , 'd' }
      +	 * name = { 'a', 'b', 'c' , 'd' }
      +	 * startIndex = 1
      +	 * isCaseSensitive = true
      +	 * result => true
      +	 * 
      + *
    2. + *
    3. +	 * fragment = { 'b', 'c' , 'd' }
      +	 * name = { 'a', 'b', 'C' , 'd' }
      +	 * startIndex = 1
      +	 * isCaseSensitive = true
      +	 * result => false
      +	 * 
      + *
    4. + *
    5. +	 * fragment = { 'b', 'c' , 'd' }
      +	 * name = { 'a', 'b', 'C' , 'd' }
      +	 * startIndex = 0
      +	 * isCaseSensitive = false
      +	 * result => false
      +	 * 
      + *
    6. + *
    7. +	 * fragment = { 'b', 'c' , 'd' }
      +	 * name = { 'a', 'b'}
      +	 * startIndex = 0
      +	 * isCaseSensitive = true
      +	 * result => false
      +	 * 
      + *
    8. + *
    + * + * @param fragment + * the fragment to check + * @param name + * the array to check + * @param startIndex + * the starting index + * @param isCaseSensitive + * check whether or not the equality should be case sensitive + * @return true if the name contains the fragment at the starting index + * startIndex according to the + * value of isCaseSensitive, otherwise false. + * @exception NullPointerException + * if fragment or name is null. + */ + public static final boolean fragmentEquals(char[] fragment, char[] name, + int startIndex, boolean isCaseSensitive) { + int max = fragment.length; + if (name.length < max + startIndex) + return false; + if (isCaseSensitive) { + for (int i = max; --i >= 0;) + // assumes the prefix is not larger than the name + if (fragment[i] != name[i + startIndex]) + return false; + return true; + } + for (int i = max; --i >= 0;) + // assumes the prefix is not larger than the name + if (Character.toLowerCase(fragment[i]) != Character + .toLowerCase(name[i + startIndex])) + return false; + return true; + } + + /** + * Answers a hashcode for the array + * + * @param array + * the array for which a hashcode is required + * @return the hashcode + * @exception NullPointerException + * if array is null + */ + public static final int hashCode(char[] array) { + int hash = 0; + int offset = 0; + int length = array.length; + if (length < 16) { + for (int i = length; i > 0; i--) + hash = (hash * 37) + array[offset++]; + } else { + // only sample some characters + int skip = length / 8; + for (int i = length; i > 0; i -= skip, offset += skip) + hash = (hash * 39) + array[offset]; + } + return hash & 0x7FFFFFFF; + } + + /** + * Answers true if c is a whitespace according to the JLS (\u000a, + * \u000c, \u000d, \u0009), otherwise false. + *
    + *
    + * For example: + *
      + *
    1. +	 * c = ' '
      +	 * result => true
      +	 * 
      + *
    2. + *
    3. +	 * c = '\u3000'
      +	 * result => false
      +	 * 
      + *
    4. + *
    + * + * @param c + * the character to check + * @return true if c is a whitespace according to the JLS, otherwise false. + */ + public static boolean isWhitespace(char c) { + switch (c) { + case 10: /* \ u000a: LINE FEED */ + case 12: /* \ u000c: FORM FEED */ + case 13: /* \ u000d: CARRIAGE RETURN */ + case 32: /* \ u0020: SPACE */ + case 9: /* \ u0009: HORIZONTAL TABULATION */ + return true; + default: + return false; + } + } + + /** + * Answers the first index in the array for which the corresponding + * character is + * equal to toBeFound. Answers -1 if no occurrence of this character is + * found. + *
    + *
    + * For example: + *
      + *
    1. +	 * toBeFound = 'c'
      +	 * array = { ' a', 'b', 'c', 'd' }
      +	 * result => 2
      +	 * 
      + *
    2. + *
    3. +	 * toBeFound = 'e'
      +	 * array = { ' a', 'b', 'c', 'd' }
      +	 * result => -1
      +	 * 
      + *
    4. + *
    + * + * @param toBeFound + * the character to search + * @param array + * the array to be searched + * @return the first index in the array for which the corresponding + * character is + * equal to toBeFound, -1 otherwise + * @exception NullPointerException + * if array is null + */ + public static final int indexOf(char toBeFound, char[] array) { + for (int i = 0; i < array.length; i++) + if (toBeFound == array[i]) + return i; + return -1; + } + + /** + * Answers the first index in the array for which the corresponding + * character is + * equal to toBeFound starting the search at index start. + * Answers -1 if no occurrence of this character is found. + *
    + *
    + * For example: + *
      + *
    1. +	 * toBeFound = 'c'
      +	 * array = { ' a', 'b', 'c', 'd' }
      +	 * start = 2
      +	 * result => 2
      +	 * 
      + *
    2. + *
    3. +	 * toBeFound = 'c'
      +	 * array = { ' a', 'b', 'c', 'd' }
      +	 * start = 3
      +	 * result => -1
      +	 * 
      + *
    4. + *
    5. +	 * toBeFound = 'e'
      +	 * array = { ' a', 'b', 'c', 'd' }
      +	 * start = 1
      +	 * result => -1
      +	 * 
      + *
    6. + *
    + * + * @param toBeFound + * the character to search + * @param array + * the array to be searched + * @param start + * the starting index + * @return the first index in the array for which the corresponding + * character is + * equal to toBeFound, -1 otherwise + * @exception NullPointerException + * if array is null + * @exception ArrayIndexOutOfBoundsException + * if start is lower than 0 + */ + public static final int indexOf(char toBeFound, char[] array, int start) { + for (int i = start; i < array.length; i++) + if (toBeFound == array[i]) + return i; + return -1; + } + + /** + * Answers the last index in the array for which the corresponding character + * is + * equal to toBeFound starting from the end of the array. + * Answers -1 if no occurrence of this character is found. + *
    + *
    + * For example: + *
      + *
    1. +	 * toBeFound = 'c'
      +	 * array = { ' a', 'b', 'c', 'd' , 'c', 'e' }
      +	 * result => 4
      +	 * 
      + *
    2. + *
    3. +	 * toBeFound = 'e'
      +	 * array = { ' a', 'b', 'c', 'd' }
      +	 * result => -1
      +	 * 
      + *
    4. + *
    + * + * @param toBeFound + * the character to search + * @param array + * the array to be searched + * @return the last index in the array for which the corresponding character + * is + * equal to toBeFound starting from the end of the array, -1 + * otherwise + * @exception NullPointerException + * if array is null + */ + public static final int lastIndexOf(char toBeFound, char[] array) { + for (int i = array.length; --i >= 0;) + if (toBeFound == array[i]) + return i; + return -1; + } + + /** + * Answers the last index in the array for which the corresponding character + * is + * equal to toBeFound stopping at the index startIndex. + * Answers -1 if no occurrence of this character is found. + *
    + *
    + * For example: + *
      + *
    1. +	 * toBeFound = 'c'
      +	 * array = { ' a', 'b', 'c', 'd' }
      +	 * startIndex = 2
      +	 * result => 2
      +	 * 
      + *
    2. + *
    3. +	 * toBeFound = 'c'
      +	 * array = { ' a', 'b', 'c', 'd', 'e' }
      +	 * startIndex = 3
      +	 * result => -1
      +	 * 
      + *
    4. + *
    5. +	 * toBeFound = 'e'
      +	 * array = { ' a', 'b', 'c', 'd' }
      +	 * startIndex = 0
      +	 * result => -1
      +	 * 
      + *
    6. + *
    + * + * @param toBeFound + * the character to search + * @param array + * the array to be searched + * @param startIndex + * the stopping index + * @return the last index in the array for which the corresponding character + * is + * equal to toBeFound stopping at the index startIndex, -1 otherwise + * @exception NullPointerException + * if array is null + * @exception ArrayIndexOutOfBoundsException + * if startIndex is lower than 0 + */ + public static final int lastIndexOf(char toBeFound, char[] array, + int startIndex) { + for (int i = array.length; --i >= startIndex;) + if (toBeFound == array[i]) + return i; + return -1; + } + + /** + * Answers the last index in the array for which the corresponding character + * is + * equal to toBeFound starting from endIndex to startIndex. + * Answers -1 if no occurrence of this character is found. + *
    + *
    + * For example: + *
      + *
    1. +	 * toBeFound = 'c'
      +	 * array = { ' a', 'b', 'c', 'd' }
      +	 * startIndex = 2
      +	 * endIndex = 2
      +	 * result => 2
      +	 * 
      + *
    2. + *
    3. +	 * toBeFound = 'c'
      +	 * array = { ' a', 'b', 'c', 'd', 'e' }
      +	 * startIndex = 3
      +	 * endIndex = 4
      +	 * result => -1
      +	 * 
      + *
    4. + *
    5. +	 * toBeFound = 'e'
      +	 * array = { ' a', 'b', 'c', 'd' }
      +	 * startIndex = 0
      +	 * endIndex = 3
      +	 * result => -1
      +	 * 
      + *
    6. + *
    + * + * @param toBeFound + * the character to search + * @param array + * the array to be searched + * @param startIndex + * the stopping index + * @param endIndex + * the starting index + * @return the last index in the array for which the corresponding character + * is + * equal to toBeFound starting from endIndex to startIndex, -1 + * otherwise + * @exception NullPointerException + * if array is null + * @exception ArrayIndexOutOfBoundsException + * if endIndex is greater or equals to array length or + * starting is lower than 0 + */ + public static final int lastIndexOf(char toBeFound, char[] array, + int startIndex, int endIndex) { + for (int i = endIndex; --i >= startIndex;) + if (toBeFound == array[i]) + return i; + return -1; + } + + /** + * Answers the last portion of a name given a separator. + *
    + *
    + * For example, + *
    +	 * lastSegment("java.lang.Object".toCharArray(),'.') --> Object
    +	 * 
    + * + * @param array + * the array + * @param separator + * the given separator + * @return the last portion of a name given a separator + * @exception NullPointerException + * if array is null + */ + final static public char[] lastSegment(char[] array, char separator) { + int pos = lastIndexOf(separator, array); + if (pos < 0) + return array; + return subarray(array, pos + 1, array.length); + } + + /** + * Answers true if the pattern matches the given name, false otherwise. This + * char[] pattern matching + * accepts wild-cards '*' and '?'. + * + * When not case sensitive, the pattern is assumed to already be lowercased, + * the + * name will be lowercased character per character as comparing. + * If name is null, the answer is false. + * If pattern is null, the answer is true if name is not null. + *
    + *
    + * For example: + *
      + *
    1. +	 * pattern = { '?', 'b', '*' }
      +	 * name = { 'a', 'b', 'c' , 'd' }
      +	 * isCaseSensitive = true
      +	 * result => true
      +	 * 
      + *
    2. + *
    3. +	 * pattern = { '?', 'b', '?' }
      +	 * name = { 'a', 'b', 'c' , 'd' }
      +	 * isCaseSensitive = true
      +	 * result => false
      +	 * 
      + *
    4. + *
    5. +	 * pattern = { 'b', '*' }
      +	 * name = { 'a', 'b', 'c' , 'd' }
      +	 * isCaseSensitive = true
      +	 * result => false
      +	 * 
      + *
    6. + *
    + * + * @param pattern + * the given pattern + * @param name + * the given name + * @param isCaseSensitive + * flag to know whether or not the matching should be case + * sensitive + * @return true if the pattern matches the given name, false otherwise + */ + public static final boolean match(char[] pattern, char[] name, + boolean isCaseSensitive) { + if (name == null) + return false; // null name cannot match + if (pattern == null) + return true; // null pattern is equivalent to '*' + return match(pattern, 0, pattern.length, name, 0, name.length, + isCaseSensitive, true); + } + + /** + * Answers true if the a sub-pattern matches the subpart of the given name, + * false otherwise. + * char[] pattern matching, accepting wild-cards '*' and '?'. Can match only + * subset of name/pattern. + * end positions are non-inclusive. + * The subpattern is defined by the patternStart and pattternEnd positions. + * When not case sensitive, the pattern is assumed to already be lowercased, + * the + * name will be lowercased character per character as comparing. + *
    + *
    + * For example: + *
      + *
    1. +	 * pattern = { '?', 'b', '*' }
      +	 * patternStart = 1
      +	 * patternEnd = 3
      +	 * name = { 'a', 'b', 'c' , 'd' }
      +	 * nameStart = 1
      +	 * nameEnd = 4
      +	 * isCaseSensitive = true
      +	 * result => true
      +	 * 
      + *
    2. + *
    3. +	 * pattern = { '?', 'b', '*' }
      +	 * patternStart = 1
      +	 * patternEnd = 2
      +	 * name = { 'a', 'b', 'c' , 'd' }
      +	 * nameStart = 1
      +	 * nameEnd = 2
      +	 * isCaseSensitive = true
      +	 * result => false
      +	 * 
      + *
    4. + *
    + * + * @param pattern + * the given pattern + * @param patternStart + * the given pattern start + * @param patternEnd + * the given pattern end + * @param name + * the given name + * @param nameStart + * the given name start + * @param nameEnd + * the given name end + * @param isCaseSensitive + * flag to know if the matching should be case sensitive + * @return true if the a sub-pattern matches the subpart of the given name, + * false otherwise + */ + public static final boolean match(char[] pattern, int patternStart, + int patternEnd, char[] name, int nameStart, int nameEnd, + boolean isCaseSensitive) { + return match(pattern, patternStart, patternEnd, name, nameStart, + nameEnd, isCaseSensitive, false); + } + + public static final boolean match(char[] pattern, int patternStart, + int patternEnd, char[] name, int nameStart, int nameEnd, + boolean isCaseSensitive, boolean allowEscaping) { + if (name == null) + return false; // null name cannot match + if (pattern == null) + return true; // null pattern is equivalent to '*' + int iPattern = patternStart; + int iName = nameStart; + if (patternEnd < 0) + patternEnd = pattern.length; + if (nameEnd < 0) + nameEnd = name.length; + /* check first segment */ + char patternChar = 0; + boolean isEscaped = false; + while ((iPattern < patternEnd) + && ((patternChar = pattern[iPattern]) != '*' || (patternChar == '*' && isEscaped))) { + if (allowEscaping && pattern[iPattern] == '\\' && !isEscaped) { + iPattern++; + isEscaped = true; + continue; + } else + isEscaped = false; + if (iName == nameEnd) + return false; + if (patternChar != (isCaseSensitive ? name[iName] : Character + .toLowerCase(name[iName])) && patternChar != '?') { + return false; + } + iName++; + iPattern++; + patternChar = 0; + } + /* check sequence of star+segment */ + int segmentStart; + if (patternChar == '*') { + segmentStart = ++iPattern; // skip star + } else { + segmentStart = 0; // force iName check + } + int prefixStart = iName; + checkSegment: while (iName < nameEnd) { + if (iPattern == patternEnd) { + iPattern = segmentStart; // mismatch - restart current segment + iName = ++prefixStart; + continue checkSegment; + } + /* segment is ending */ + if ((patternChar = pattern[iPattern]) == '*') { + segmentStart = ++iPattern; // skip start + if (segmentStart == patternEnd) { + return true; + } + prefixStart = iName; + continue checkSegment; + } + /* check current name character */ + if ((isCaseSensitive ? name[iName] : Character + .toLowerCase(name[iName])) != patternChar + && patternChar != '?') { + iPattern = segmentStart; // mismatch - restart current segment + iName = ++prefixStart; + continue checkSegment; + } + iName++; + iPattern++; + } + return (segmentStart == patternEnd) + || (iName == nameEnd && iPattern == patternEnd) + || (iPattern == patternEnd - 1 && pattern[iPattern] == '*'); + } + + /** + * Answers true if the pattern matches the filepath using the pathSepatator, + * false otherwise. + * + * Path char[] pattern matching, accepting wild-cards '**', '*' and '?' + * (using Ant directory tasks + * conventions, also see + * "http://jakarta.apache.org/ant/manual/dirtasks.html#defaultexcludes"). + * Path pattern matching is enhancing regular pattern matching in supporting + * extra rule where '**' represent + * any folder combination. + * Special rules: + * - foo\ is equivalent to foo\** + * - *.java is equivalent to **\*.java + * When not case sensitive, the pattern is assumed to already be lowercased, + * the + * name will be lowercased character per character as comparing. + * + * @param pattern + * the given pattern + * @param filepath + * the given path + * @param isCaseSensitive + * to find out whether or not the matching should be case + * sensitive + * @param pathSeparator + * the given path separator + * @return true if the pattern matches the filepath using the pathSepatator, + * false otherwise + */ + public static final boolean pathMatch(char[] pattern, char[] filepath, + boolean isCaseSensitive, char pathSeparator) { + if (filepath == null) + return false; // null name cannot match + if (pattern == null) + return true; // null pattern is equivalent to '*' + // special case: pattern foo is equivalent to **\foo (not absolute) + boolean freeLeadingDoubleStar; + // offsets inside pattern + int pSegmentStart, pLength = pattern.length; + freeLeadingDoubleStar = (pattern[0] != pathSeparator); + if (freeLeadingDoubleStar) { + pSegmentStart = 0; + } else { + pSegmentStart = 1; + } + int pSegmentEnd = CharOperation.indexOf(pathSeparator, pattern, + pSegmentStart + 1); + if (pSegmentEnd < 0) + pSegmentEnd = pLength; + // special case: pattern foo\ is equivalent to foo\** + boolean freeTrailingDoubleStar = pattern[pLength - 1] == pathSeparator; + // offsets inside filepath + int fSegmentStart, fLength = filepath.length; + if (filepath[0] != pathSeparator) { + fSegmentStart = 0; + } else { + fSegmentStart = 1; + } + if (fSegmentStart != pSegmentStart) { + return false; // both must start with a separator or none. + } + int fSegmentEnd = CharOperation.indexOf(pathSeparator, filepath, + fSegmentStart + 1); + if (fSegmentEnd < 0) + fSegmentEnd = fLength; + // first segments + while (pSegmentStart < pLength + && !freeLeadingDoubleStar + && !(pSegmentEnd == pLength && freeTrailingDoubleStar || (pSegmentEnd == pSegmentStart + 2 + && pattern[pSegmentStart] == '*' && pattern[pSegmentStart + 1] == '*'))) { + if (fSegmentStart >= fLength) + return false; + if (!CharOperation.match(pattern, pSegmentStart, pSegmentEnd, + filepath, fSegmentStart, fSegmentEnd, isCaseSensitive)) { + return false; + } + // jump to next segment + pSegmentEnd = CharOperation.indexOf(pathSeparator, pattern, + pSegmentStart = pSegmentEnd + 1); + // skip separator + if (pSegmentEnd < 0) + pSegmentEnd = pLength; + fSegmentEnd = CharOperation.indexOf(pathSeparator, filepath, + fSegmentStart = fSegmentEnd + 1); + // skip separator + if (fSegmentEnd < 0) + fSegmentEnd = fLength; + } + /* check sequence of doubleStar+segment */ + int pSegmentRestart; + if ((pSegmentStart >= pLength && freeTrailingDoubleStar) + || (pSegmentEnd == pSegmentStart + 2 + && pattern[pSegmentStart] == '*' && pattern[pSegmentStart + 1] == '*')) { + pSegmentEnd = CharOperation.indexOf(pathSeparator, pattern, + pSegmentStart = pSegmentEnd + 1); + // skip separator + if (pSegmentEnd < 0) + pSegmentEnd = pLength; + pSegmentRestart = pSegmentStart; + } else { + if (pSegmentStart >= pLength) + return fSegmentStart >= fLength; // true if filepath is done too. + pSegmentRestart = 0; // force fSegmentStart check + } + int fSegmentRestart = fSegmentStart; + checkSegment: while (fSegmentStart < fLength) { + if (pSegmentStart >= pLength) { + if (freeTrailingDoubleStar) + return true; + // mismatch - restart current path segment + pSegmentEnd = CharOperation.indexOf(pathSeparator, pattern, + pSegmentStart = pSegmentRestart); + if (pSegmentEnd < 0) + pSegmentEnd = pLength; + fSegmentRestart = CharOperation.indexOf(pathSeparator, + filepath, fSegmentRestart + 1); + // skip separator + if (fSegmentRestart < 0) { + fSegmentRestart = fLength; + } else { + fSegmentRestart++; + } + fSegmentEnd = CharOperation.indexOf(pathSeparator, filepath, + fSegmentStart = fSegmentRestart); + if (fSegmentEnd < 0) + fSegmentEnd = fLength; + continue checkSegment; + } + /* path segment is ending */ + if (pSegmentEnd == pSegmentStart + 2 + && pattern[pSegmentStart] == '*' + && pattern[pSegmentStart + 1] == '*') { + pSegmentEnd = CharOperation.indexOf(pathSeparator, pattern, + pSegmentStart = pSegmentEnd + 1); + // skip separator + if (pSegmentEnd < 0) + pSegmentEnd = pLength; + pSegmentRestart = pSegmentStart; + fSegmentRestart = fSegmentStart; + if (pSegmentStart >= pLength) + return true; + continue checkSegment; + } + /* chech current path segment */ + if (!CharOperation.match(pattern, pSegmentStart, pSegmentEnd, + filepath, fSegmentStart, fSegmentEnd, isCaseSensitive)) { + // mismatch - restart current path segment + pSegmentEnd = CharOperation.indexOf(pathSeparator, pattern, + pSegmentStart = pSegmentRestart); + if (pSegmentEnd < 0) + pSegmentEnd = pLength; + fSegmentRestart = CharOperation.indexOf(pathSeparator, + filepath, fSegmentRestart + 1); + // skip separator + if (fSegmentRestart < 0) { + fSegmentRestart = fLength; + } else { + fSegmentRestart++; + } + fSegmentEnd = CharOperation.indexOf(pathSeparator, filepath, + fSegmentStart = fSegmentRestart); + if (fSegmentEnd < 0) + fSegmentEnd = fLength; + continue checkSegment; + } + // jump to next segment + pSegmentEnd = CharOperation.indexOf(pathSeparator, pattern, + pSegmentStart = pSegmentEnd + 1); + // skip separator + if (pSegmentEnd < 0) + pSegmentEnd = pLength; + fSegmentEnd = CharOperation.indexOf(pathSeparator, filepath, + fSegmentStart = fSegmentEnd + 1); + // skip separator + if (fSegmentEnd < 0) + fSegmentEnd = fLength; + } + return (pSegmentRestart >= pSegmentEnd) + || (fSegmentStart >= fLength && pSegmentStart >= pLength) + || (pSegmentStart == pLength - 2 + && pattern[pSegmentStart] == '*' && pattern[pSegmentStart + 1] == '*') + || (pSegmentStart == pLength && freeTrailingDoubleStar); + } + + /** + * Answers the number of occurrences of the given character in the given + * array, 0 if any. + * + *
    + *
    + * For example: + *
      + *
    1. +	 * toBeFound = 'b'
      +	 * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
      +	 * result => 3
      +	 * 
      + *
    2. + *
    3. +	 * toBeFound = 'c'
      +	 * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
      +	 * result => 0
      +	 * 
      + *
    4. + *
    + * + * @param toBeFound + * the given character + * @param array + * the given array + * @return the number of occurrences of the given character in the given + * array, 0 if any + * @exception NullPointerException + * if array is null + */ + public static final int occurencesOf(char toBeFound, char[] array) { + int count = 0; + for (char element : array) + if (toBeFound == element) + count++; + return count; + } + + /** + * Answers the number of occurrences of the given character in the given + * array starting + * at the given index, 0 if any. + * + *
    + *
    + * For example: + *
      + *
    1. +	 * toBeFound = 'b'
      +	 * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
      +	 * start = 2
      +	 * result => 2
      +	 * 
      + *
    2. + *
    3. +	 * toBeFound = 'c'
      +	 * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
      +	 * start = 0
      +	 * result => 0
      +	 * 
      + *
    4. + *
    + * + * @param toBeFound + * the given character + * @param array + * the given array + * @return the number of occurrences of the given character in the given + * array, 0 if any + * @exception NullPointerException + * if array is null + * @exception ArrayIndexOutOfBoundsException + * if start is lower than 0 + */ + public static final int occurencesOf(char toBeFound, char[] array, int start) { + int count = 0; + for (int i = start; i < array.length; i++) + if (toBeFound == array[i]) + count++; + return count; + } + + /** + * Answers true if the given name starts with the given prefix, false + * otherwise. + * The comparison is case sensitive. + *
    + *
    + * For example: + *
      + *
    1. +	 * prefix = { 'a' , 'b' }
      +	 * name = { 'a' , 'b', 'b', 'a', 'b', 'a' }
      +	 * result => true
      +	 * 
      + *
    2. + *
    3. +	 * prefix = { 'a' , 'c' }
      +	 * name = { 'a' , 'b', 'b', 'a', 'b', 'a' }
      +	 * result => false
      +	 * 
      + *
    4. + *
    + * + * @param prefix + * the given prefix + * @param name + * the given name + * @return true if the given name starts with the given prefix, false + * otherwise + * @exception NullPointerException + * if the given name is null or if the given prefix is null + */ + public static final boolean prefixEquals(char[] prefix, char[] name) { + int max = prefix.length; + if (name.length < max) + return false; + for (int i = max; --i >= 0;) + // assumes the prefix is not larger than the name + if (prefix[i] != name[i]) + return false; + return true; + } + + /** + * Answers true if the given name starts with the given prefix, false + * otherwise. + * isCaseSensitive is used to find out whether or not the comparison should + * be case sensitive. + *
    + *
    + * For example: + *
      + *
    1. +	 * prefix = { 'a' , 'B' }
      +	 * name = { 'a' , 'b', 'b', 'a', 'b', 'a' }
      +	 * isCaseSensitive = false
      +	 * result => true
      +	 * 
      + *
    2. + *
    3. +	 * prefix = { 'a' , 'B' }
      +	 * name = { 'a' , 'b', 'b', 'a', 'b', 'a' }
      +	 * isCaseSensitive = true
      +	 * result => false
      +	 * 
      + *
    4. + *
    + * + * @param prefix + * the given prefix + * @param name + * the given name + * @param isCaseSensitive + * to find out whether or not the comparison should be case + * sensitive + * @return true if the given name starts with the given prefix, false + * otherwise + * @exception NullPointerException + * if the given name is null or if the given prefix is null + */ + public static final boolean prefixEquals(char[] prefix, char[] name, + boolean isCaseSensitive) { + int max = prefix.length; + if (name.length < max) + return false; + if (isCaseSensitive) { + for (int i = max; --i >= 0;) + // assumes the prefix is not larger than the name + if (prefix[i] != name[i]) + return false; + return true; + } + for (int i = max; --i >= 0;) + // assumes the prefix is not larger than the name + if (Character.toLowerCase(prefix[i]) != Character + .toLowerCase(name[i])) + return false; + return true; + } + + /** + * Replace all occurrence of the character to be replaced with the + * remplacement character in the + * given array. + *
    + *
    + * For example: + *
      + *
    1. +	 * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
      +	 * toBeReplaced = 'b'
      +	 * replacementChar = 'a'
      +	 * result => No returned value, but array is now equals to { 'a' , 'a', 'a',
      +	 * 'a', 'a', 'a' }
      +	 * 
      + *
    2. + *
    3. +	 * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
      +	 * toBeReplaced = 'c'
      +	 * replacementChar = 'a'
      +	 * result => No returned value, but array is now equals to { 'a' , 'b', 'b',
      +	 * 'a', 'b', 'a' }
      +	 * 
      + *
    4. + *
    + * + * @param array + * the given array + * @param toBeReplaced + * the character to be replaced + * @param replacementChar + * the replacement character + * @exception NullPointerException + * if the given array is null + */ + public static final void replace(char[] array, char toBeReplaced, + char replacementChar) { + if (toBeReplaced != replacementChar) { + for (int i = 0, max = array.length; i < max; i++) { + if (array[i] == toBeReplaced) + array[i] = replacementChar; + } + } + } + + /** + * Answers a new array of characters with substitutions. No side-effect is + * operated on the original + * array, in case no substitution happened, then the result is the same as + * the + * original one. + *
    + *
    + * For example: + *
      + *
    1. +	 * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
      +	 * toBeReplaced = { 'b' }
      +	 * replacementChar = { 'a', 'a' }
      +	 * result => { 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a' }
      +	 * 
      + *
    2. + *
    3. +	 * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
      +	 * toBeReplaced = { 'c' }
      +	 * replacementChar = { 'a' }
      +	 * result => { 'a' , 'b', 'b', 'a', 'b', 'a' }
      +	 * 
      + *
    4. + *
    + * + * @param array + * the given array + * @param toBeReplaced + * characters to be replaced + * @param replacementChars + * the replacement characters + * @return a new array of characters with substitutions or the given array + * if none + * @exception NullPointerException + * if the given array is null + */ + public static final char[] replace(char[] array, char[] toBeReplaced, + char[] replacementChars) { + int max = array.length; + int replacedLength = toBeReplaced.length; + int replacementLength = replacementChars.length; + int[] starts = new int[5]; + int occurrenceCount = 0; + if (!equals(toBeReplaced, replacementChars)) { + next: for (int i = 0; i < max; i++) { + int j = 0; + while (j < replacedLength) { + if (i + j == max) + continue next; + if (array[i + j] != toBeReplaced[j++]) + continue next; + } + if (occurrenceCount == starts.length) { + System.arraycopy(starts, 0, + starts = new int[occurrenceCount * 2], 0, + occurrenceCount); + } + starts[occurrenceCount++] = i; + } + } + if (occurrenceCount == 0) + return array; + char[] result = new char[max + occurrenceCount + * (replacementLength - replacedLength)]; + int inStart = 0, outStart = 0; + for (int i = 0; i < occurrenceCount; i++) { + int offset = starts[i] - inStart; + System.arraycopy(array, inStart, result, outStart, offset); + inStart += offset; + outStart += offset; + System.arraycopy(replacementChars, 0, result, outStart, + replacementLength); + inStart += replacedLength; + outStart += replacementLength; + } + System.arraycopy(array, inStart, result, outStart, max - inStart); + return result; + } + + /** + * Return a new array which is the split of the given array using the given + * divider and triming each subarray to remove + * whitespaces equals to ' '. + *
    + *
    + * For example: + *
      + *
    1. +	 * divider = 'b'
      +	 * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
      +	 * result => { { 'a' }, { }, { 'a' }, { 'a' } }
      +	 * 
      + *
    2. + *
    3. +	 * divider = 'c'
      +	 * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
      +	 * result => { { 'a', 'b', 'b', 'a', 'b', 'a' } }
      +	 * 
      + *
    4. + *
    5. +	 * divider = 'b'
      +	 * array = { 'a' , ' ', 'b', 'b', 'a', 'b', 'a' }
      +	 * result => { { 'a' }, { }, { 'a' }, { 'a' } }
      +	 * 
      + *
    6. + *
    7. +	 * divider = 'c'
      +	 * array = { ' ', ' ', 'a' , 'b', 'b', 'a', 'b', 'a', ' ' }
      +	 * result => { { 'a', 'b', 'b', 'a', 'b', 'a' } }
      +	 * 
      + *
    8. + *
    + * + * @param divider + * the given divider + * @param array + * the given array + * @return a new array which is the split of the given array using the given + * divider and triming each subarray to remove + * whitespaces equals to ' ' + */ + public static final char[][] splitAndTrimOn(char divider, char[] array) { + if (array == null) + return NO_CHAR_CHAR; + final int length = array.length; + if (length == 0) + return NO_CHAR_CHAR; + int wordCount = 1; + for (int i = 0; i < length; i++) + if (array[i] == divider) + wordCount++; + char[][] split = new char[wordCount][]; + int last = 0, currentWord = 0; + for (int i = 0; i < length; i++) { + if (array[i] == divider) { + int start = last, end = i - 1; + while (start < i && array[start] == ' ') + start++; + while (end > start && array[end] == ' ') + end--; + split[currentWord] = new char[end - start + 1]; + System.arraycopy(array, start, split[currentWord++], 0, end + - start + 1); + last = i + 1; + } + } + int start = last, end = length - 1; + while (start < length && array[start] == ' ') + start++; + while (end > start && array[end] == ' ') + end--; + split[currentWord] = new char[end - start + 1]; + System.arraycopy(array, start, split[currentWord++], 0, end - start + 1); + return split; + } + + /** + * Return a new array which is the split of the given array using the given + * divider. + *
    + *
    + * For example: + *
      + *
    1. +	 * divider = 'b'
      +	 * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
      +	 * result => { { 'a' }, { }, { 'a' }, { 'a' } }
      +	 * 
      + *
    2. + *
    3. +	 * divider = 'c'
      +	 * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
      +	 * result => { { 'a', 'b', 'b', 'a', 'b', 'a' } }
      +	 * 
      + *
    4. + *
    5. +	 * divider = 'c'
      +	 * array = { ' ', ' ', 'a' , 'b', 'b', 'a', 'b', 'a', ' ' }
      +	 * result => { { ' ', 'a', 'b', 'b', 'a', 'b', 'a', ' ' } }
      +	 * 
      + *
    6. + *
    + * + * @param divider + * the given divider + * @param array + * the given array + * @return a new array which is the split of the given array using the given + * divider + */ + public static final char[][] splitOn(char divider, char[] array) { + if (array == null) + return NO_CHAR_CHAR; + final int length = array.length; + if (length == 0) + return NO_CHAR_CHAR; + int wordCount = 1; + for (int i = 0; i < length; i++) + if (array[i] == divider) + wordCount++; + char[][] split = new char[wordCount][]; + int last = 0, currentWord = 0; + for (int i = 0; i < length; i++) { + if (array[i] == divider) { + split[currentWord] = new char[i - last]; + System.arraycopy(array, last, split[currentWord++], 0, i - last); + last = i + 1; + } + } + split[currentWord] = new char[length - last]; + System.arraycopy(array, last, split[currentWord], 0, length - last); + return split; + } + + /** + * Return a new array which is the split of the given array using the given + * divider. The given end + * is exclusive and the given start is inclusive. + *
    + *
    + * For example: + *
      + *
    1. +	 * divider = 'b'
      +	 * array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
      +	 * start = 2
      +	 * end = 5
      +	 * result => { { }, { }, { 'a' } }
      +	 * 
      + *
    2. + *
    + * + * @param divider + * the given divider + * @param array + * the given array + * @param start + * the given starting index + * @param end + * the given ending index + * @return a new array which is the split of the given array using the given + * divider + * @exception ArrayIndexOutOfBoundsException + * if start is lower than 0 or end is greater than the array + * length + */ + public static final char[][] splitOn(char divider, char[] array, int start, + int end) { + if (array == null) + return NO_CHAR_CHAR; + final int length = array.length; + if (length == 0 || start > end) + return NO_CHAR_CHAR; + int wordCount = 1; + for (int i = start; i < end; i++) + if (array[i] == divider) + wordCount++; + char[][] split = new char[wordCount][]; + int last = start, currentWord = 0; + for (int i = start; i < end; i++) { + if (array[i] == divider) { + split[currentWord] = new char[i - last]; + System.arraycopy(array, last, split[currentWord++], 0, i - last); + last = i + 1; + } + } + split[currentWord] = new char[end - last]; + System.arraycopy(array, last, split[currentWord], 0, end - last); + return split; + } + + /** + * Answers a new array which is a copy of the given array starting at the + * given start and + * ending at the given end. The given start is inclusive and the given end + * is exclusive. + * Answers null if start is greater than end, if start is lower than 0 or if + * end is greater + * than the length of the given array. If end equals -1, it is converted to + * the array length. + *
    + *
    + * For example: + *
      + *
    1. +	 * array = { { 'a' } , { 'b' } }
      +	 * start = 0
      +	 * end = 1
      +	 * result => { { 'a' } }
      +	 * 
      + *
    2. + *
    3. +	 * array = { { 'a' } , { 'b' } }
      +	 * start = 0
      +	 * end = -1
      +	 * result => { { 'a' }, { 'b' } }
      +	 * 
      + *
    4. + *
    + * + * @param array + * the given array + * @param start + * the given starting index + * @param end + * the given ending index + * @return a new array which is a copy of the given array starting at the + * given start and + * ending at the given end + * @exception NullPointerException + * if the given array is null + */ + public static final char[][] subarray(char[][] array, int start, int end) { + if (end == -1) + end = array.length; + if (start > end) + return null; + if (start < 0) + return null; + if (end > array.length) + return null; + char[][] result = new char[end - start][]; + System.arraycopy(array, start, result, 0, end - start); + return result; + } + + /** + * Answers a new array which is a copy of the given array starting at the + * given start and + * ending at the given end. The given start is inclusive and the given end + * is exclusive. + * Answers null if start is greater than end, if start is lower than 0 or if + * end is greater + * than the length of the given array. If end equals -1, it is converted to + * the array length. + *
    + *
    + * For example: + *
      + *
    1. +	 * array = { 'a' , 'b' }
      +	 * start = 0
      +	 * end = 1
      +	 * result => { 'a' }
      +	 * 
      + *
    2. + *
    3. +	 * array = { 'a', 'b' }
      +	 * start = 0
      +	 * end = -1
      +	 * result => { 'a' , 'b' }
      +	 * 
      + *
    4. + *
    + * + * @param array + * the given array + * @param start + * the given starting index + * @param end + * the given ending index + * @return a new array which is a copy of the given array starting at the + * given start and + * ending at the given end + * @exception NullPointerException + * if the given array is null + */ + public static final char[] subarray(char[] array, int start, int end) { + if (end == -1) + end = array.length; + if (start > end) + return null; + if (start < 0) + return null; + if (end > array.length) + return null; + char[] result = new char[end - start]; + System.arraycopy(array, start, result, 0, end - start); + return result; + } + + /** + * Answers the result of a char[] conversion to lowercase. Answers null if + * the given chars array is null. + *
    + * NOTE: If no conversion was necessary, then answers back the argument one. + *
    + *
    + * For example: + *
      + *
    1. +	 * chars = { 'a' , 'b' }
      +	 * result => { 'a' , 'b' }
      +	 * 
      + *
    2. + *
    3. +	 * array = { 'A', 'b' }
      +	 * result => { 'a' , 'b' }
      +	 * 
      + *
    4. + *
    + * + * @param chars + * the chars to convert + * @return the result of a char[] conversion to lowercase + */ + final static public char[] toLowerCase(char[] chars) { + if (chars == null) + return null; + int length = chars.length; + char[] lowerChars = null; + for (int i = 0; i < length; i++) { + char c = chars[i]; + char lc = Character.toLowerCase(c); + if ((c != lc) || (lowerChars != null)) { + if (lowerChars == null) { + System.arraycopy(chars, 0, lowerChars = new char[length], + 0, i); + } + lowerChars[i] = lc; + } + } + return lowerChars == null ? chars : lowerChars; + } + + /** + * Answers a new array removing leading and trailing spaces (' '). Answers + * the given array if there is no + * space characters to remove. + *
    + *
    + * For example: + *
      + *
    1. +	 * chars = { ' ', 'a' , 'b', ' ', ' ' }
      +	 * result => { 'a' , 'b' }
      +	 * 
      + *
    2. + *
    3. +	 * array = { 'A', 'b' }
      +	 * result => { 'A' , 'b' }
      +	 * 
      + *
    4. + *
    + * + * @param chars + * the given array + * @return a new array removing leading and trailing spaces (' ') + */ + final static public char[] trim(char[] chars) { + if (chars == null) + return null; + int start = 0, length = chars.length, end = length - 1; + while (start < length && chars[start] == ' ') { + start++; + } + while (end > start && chars[end] == ' ') { + end--; + } + if (start != 0 || end != length - 1) { + return subarray(chars, start, end + 1); + } + return chars; + } + + /** + * Answers a string which is the concatenation of the given array using the + * '.' as a separator. + *
    + *
    + * For example: + *
      + *
    1. +	 * array = { { 'a' } , { 'b' } }
      +	 * result => "a.b"
      +	 * 
      + *
    2. + *
    3. +	 * array = { { ' ', 'a' } , { 'b' } }
      +	 * result => " a.b"
      +	 * 
      + *
    4. + *
    + * + * @param array + * the given array + * @return a string which is the concatenation of the given array using the + * '.' as a separator + */ + final static public String toString(char[][] array) { + char[] result = concatWith(array, '.'); + return new String(result); + } +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CheckersRegisry.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CheckersRegisry.java deleted file mode 100644 index 5661622..0000000 --- a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CheckersRegisry.java +++ /dev/null @@ -1,367 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009 Alena Laskavaia - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alena Laskavaia - initial API and implementation - *******************************************************************************/ -package org.eclipse.cdt.codan.internal.core; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; - -import org.eclipse.cdt.codan.core.CodanCorePlugin; -import org.eclipse.cdt.codan.core.PreferenceConstants; -import org.eclipse.cdt.codan.core.model.IChecker; -import org.eclipse.cdt.codan.core.model.ICheckersRegistry; -import org.eclipse.cdt.codan.core.model.IProblem; -import org.eclipse.cdt.codan.core.model.IProblemCategory; -import org.eclipse.cdt.codan.core.model.IProblemProfile; -import org.eclipse.cdt.codan.internal.core.model.CodanProblem; -import org.eclipse.cdt.codan.internal.core.model.CodanProblemCategory; -import org.eclipse.cdt.codan.internal.core.model.ProblemProfile; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.ProjectScope; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IExtensionPoint; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.preferences.IEclipsePreferences; - -public class CheckersRegisry implements Iterable, ICheckersRegistry { - private static final String EXTENSION_POINT_NAME = "checkers"; - private static final String CHECKER_ELEMENT = "checker"; - private static final String PROBLEM_ELEMENT = "problem"; - private static final String CATEGORY_ELEMENT = "category"; - private static final Object DEFAULT = "DEFAULT"; - private Collection checkers = new ArrayList(); - private static CheckersRegisry instance; - private HashMap profiles = new HashMap(); - private HashMap> problemList = new HashMap>(); - - private CheckersRegisry() { - instance = this; - profiles.put(DEFAULT, new ProblemProfile()); - readCheckersRegistry(); - } - - private void readCheckersRegistry() { - IExtensionPoint ep = Platform.getExtensionRegistry().getExtensionPoint( - CodanCorePlugin.PLUGIN_ID, EXTENSION_POINT_NAME); - if (ep == null) - return; - IConfigurationElement[] elements = ep.getConfigurationElements(); - // process categories - for (int i = 0; i < elements.length; i++) { - IConfigurationElement configurationElement = elements[i]; - processCategories(configurationElement); - } - // process shared problems - for (int i = 0; i < elements.length; i++) { - IConfigurationElement configurationElement = elements[i]; - processProblem(configurationElement); - } - // process checkers - for (int i = 0; i < elements.length; i++) { - IConfigurationElement configurationElement = elements[i]; - processChecker(configurationElement); - } - } - - /** - * @param configurationElement - */ - private void processCategories(IConfigurationElement configurationElement) { - if (configurationElement.getName().equals(CATEGORY_ELEMENT)) { - String id = getAtt(configurationElement, "id"); - if (id == null) - return; - String name = getAtt(configurationElement, "name"); - if (name == null) - return; - CodanProblemCategory cat = new CodanProblemCategory(id, name); - String category = getAtt(configurationElement, "parentCategory", - false); - addCategory(cat, category); - } - } - - /** - * @param configurationElement - */ - private void processChecker(IConfigurationElement configurationElement) { - try { - if (configurationElement.getName().equals(CHECKER_ELEMENT)) { - String id = getAtt(configurationElement, "id"); - if (id == null) - return; - String name = getAtt(configurationElement, "name", false); - if (name == null) - name = id; - IChecker checkerObj = null; - try { - Object checker = configurationElement - .createExecutableExtension("class"); - checkerObj = (IChecker) checker; - addChecker(checkerObj); - } catch (CoreException e) { - CodanCorePlugin.log(e); - return; - } - IConfigurationElement[] children1 = configurationElement - .getChildren("problemRef"); - boolean hasRef = false; - IConfigurationElement[] children2 = configurationElement - .getChildren(PROBLEM_ELEMENT); - if (children2 != null) { - for (IConfigurationElement ref : children2) { - IProblem p = processProblem(ref); - addRefProblem(checkerObj, p); - hasRef = true; - } - } - if (children1 != null) { - for (IConfigurationElement ref : children1) { - hasRef = true; - IProblem p = getDefaultProfile().findProblem( - ref.getAttribute("refId")); - addRefProblem(checkerObj, p); - } - } - if (!hasRef) { - CodanProblem p = new CodanProblem(id, name); - addProblem(p, null); - addRefProblem(checkerObj, p); - } - } - } catch (Exception e) { - CodanCorePlugin.log(e); - } - } - - /** - * @param configurationElement - * @return - */ - private CodanProblem processProblem( - IConfigurationElement configurationElement) { - if (configurationElement.getName().equals(PROBLEM_ELEMENT)) { - String id = getAtt(configurationElement, "id"); - if (id == null) - return null; - String name = getAtt(configurationElement, "name"); - if (name == null) - name = id; - CodanProblem p = new CodanProblem(id, name); - String category = getAtt(configurationElement, "category", false); - if (category == null) - category = "org.eclipse.cdt.codan.core.categories.ProgrammingProblems"; - addProblem(p, category); - return p; - } - return null; - } - - private static String getAtt(IConfigurationElement configurationElement, - String name) { - return getAtt(configurationElement, name, true); - } - - private static String getAtt(IConfigurationElement configurationElement, - String name, boolean req) { - String elementValue = configurationElement.getAttribute(name); - if (elementValue == null && req) - CodanCorePlugin.log("Extension " - + configurationElement.getDeclaringExtension() - .getUniqueIdentifier() - + " missing required attribute: " - + configurationElement.getName() + "." + name); - return elementValue; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.codan.core.model.ICheckersRegistry#iterator() - */ - public Iterator iterator() { - return checkers.iterator(); - } - - public static CheckersRegisry getInstance() { - if (instance == null) - new CheckersRegisry(); - return instance; - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.cdt.codan.core.model.ICheckersRegistry#addChecker(org.eclipse - * .cdt.codan.core.model.IChecker) - */ - public void addChecker(IChecker checker) { - checkers.add(checker); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.cdt.codan.core.model.ICheckersRegistry#addProblem(org.eclipse - * .cdt.codan.core.model.IProblem, java.lang.String) - */ - public void addProblem(IProblem p, String category) { - IProblemCategory cat = getDefaultProfile().findCategory(category); - if (cat == null) - cat = getDefaultProfile().getRoot(); - ((ProblemProfile) getDefaultProfile()).addProblem(p, cat); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.cdt.codan.core.model.ICheckersRegistry#addCategory(org.eclipse - * .cdt.codan.core.model.IProblemCategory, java.lang.String) - */ - public void addCategory(IProblemCategory p, String category) { - IProblemCategory cat = getDefaultProfile().findCategory(category); - if (cat == null) - cat = getDefaultProfile().getRoot(); - ((ProblemProfile) getDefaultProfile()).addCategory(p, cat); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.cdt.codan.core.model.ICheckersRegistry#addRefProblem(org. - * eclipse.cdt.codan.core.model.IChecker, - * org.eclipse.cdt.codan.core.model.IProblem) - */ - public void addRefProblem(IChecker c, IProblem p) { - Collection plist = problemList.get(c); - if (plist == null) { - plist = new ArrayList(); - problemList.put(c, plist); - } - plist.add(p); - } - - /** - * Returns list of problems registered for given checker - * @return collection of problems or null - */ - public Collection getRefProblems(IChecker checker) { - return problemList.get(checker); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.cdt.codan.core.model.ICheckersRegistry#getDefaultProfile() - */ - public IProblemProfile getDefaultProfile() { - return profiles.get(DEFAULT); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.cdt.codan.core.model.ICheckersRegistry#getWorkspaceProfile() - */ - public IProblemProfile getWorkspaceProfile() { - IProblemProfile wp = profiles.get(ResourcesPlugin.getWorkspace()); - if (wp == null) { - try { - wp = (IProblemProfile) getDefaultProfile().clone(); - // load default values - CodanPreferencesLoader loader = new CodanPreferencesLoader(wp); - loader.load(CodanCorePlugin.getDefault().getStorePreferences()); - } catch (CloneNotSupportedException e) { - wp = getDefaultProfile(); - } - } - return wp; - } - - public void updateProfile(IResource element, IProblemProfile profile) { - if (profile == null) - profiles.remove(element); - else - profiles.put(element, profile); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.cdt.codan.core.model.ICheckersRegistry#getResourceProfile - * (org.eclipse.core.resources.IResource) - */ - public IProblemProfile getResourceProfile(IResource element) { - IProblemProfile prof = profiles.get(element); - if (prof == null) { - if (element instanceof IProject) { - try { - prof = (IProblemProfile) getWorkspaceProfile().clone(); - // load default values - CodanPreferencesLoader loader = new CodanPreferencesLoader( - prof); - IEclipsePreferences node = new ProjectScope( - (IProject) element) - .getNode(CodanCorePlugin.PLUGIN_ID); - boolean useWorkspace = node.getBoolean( - PreferenceConstants.P_USE_PARENT, false); - if (!useWorkspace) { - loader.load(node); - } - updateProfile(element, prof); - } catch (CloneNotSupportedException e) { - // cant - } - } else if (element.getParent() != null) { - prof = getResourceProfile(element.getParent()); - } else { - prof = getResourceProfile(element.getProject()); - } - } else { - } - return prof; - } - - /* - * (non-Javadoc) - * - * @seeorg.eclipse.cdt.codan.core.model.ICheckersRegistry# - * getResourceProfileWorkingCopy(org.eclipse.core.resources.IResource) - */ - public IProblemProfile getResourceProfileWorkingCopy(IResource element) { - if (element instanceof IProject) { - try { - IProblemProfile prof = (IProblemProfile) getWorkspaceProfile() - .clone(); - // load default values - CodanPreferencesLoader loader = new CodanPreferencesLoader(prof); - IEclipsePreferences node = new ProjectScope((IProject) element) - .getNode(CodanCorePlugin.PLUGIN_ID); - loader.load(node); - return prof; - } catch (CloneNotSupportedException e) { - // cant - } - } - return null; - } -} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CheckersRegistry.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CheckersRegistry.java new file mode 100644 index 0000000..9a9dadc --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CheckersRegistry.java @@ -0,0 +1,442 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Alena Laskavaia + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.internal.core; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; + +import org.eclipse.cdt.codan.core.CodanCorePlugin; +import org.eclipse.cdt.codan.core.PreferenceConstants; +import org.eclipse.cdt.codan.core.model.CodanSeverity; +import org.eclipse.cdt.codan.core.model.IChecker; +import org.eclipse.cdt.codan.core.model.ICheckerWithPreferences; +import org.eclipse.cdt.codan.core.model.ICheckersRegistry; +import org.eclipse.cdt.codan.core.model.IProblem; +import org.eclipse.cdt.codan.core.model.IProblemCategory; +import org.eclipse.cdt.codan.core.model.IProblemProfile; +import org.eclipse.cdt.codan.core.model.IProblemWorkingCopy; +import org.eclipse.cdt.codan.internal.core.model.CodanProblem; +import org.eclipse.cdt.codan.internal.core.model.CodanProblemCategory; +import org.eclipse.cdt.codan.internal.core.model.ProblemProfile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.Platform; +import org.osgi.service.prefs.Preferences; + +/** + * Implementation of checker registry interface + */ +public class CheckersRegistry implements Iterable, ICheckersRegistry { + private static final String NAME_ATTR = "name"; //$NON-NLS-1$ + private static final String ID_ATTR = "id"; //$NON-NLS-1$ + private static final String EXTENSION_POINT_NAME = "checkers"; //$NON-NLS-1$ + private static final String CHECKER_ELEMENT = "checker"; //$NON-NLS-1$ + private static final String PROBLEM_ELEMENT = "problem"; //$NON-NLS-1$ + private static final String CATEGORY_ELEMENT = "category"; //$NON-NLS-1$ + private static final Object DEFAULT = "DEFAULT"; //$NON-NLS-1$ + private Collection checkers = new ArrayList(); + private static CheckersRegistry instance; + private HashMap profiles = new HashMap(); + private HashMap> problemList = new HashMap>(); + + private CheckersRegistry() { + instance = this; + profiles.put(DEFAULT, new ProblemProfile()); + readCheckersRegistry(); + } + + private void readCheckersRegistry() { + IExtensionPoint ep = Platform.getExtensionRegistry().getExtensionPoint( + CodanCorePlugin.PLUGIN_ID, EXTENSION_POINT_NAME); + if (ep == null) + return; + IConfigurationElement[] elements = ep.getConfigurationElements(); + // process categories + for (int i = 0; i < elements.length; i++) { + IConfigurationElement configurationElement = elements[i]; + processCategories(configurationElement); + } + // process shared problems + for (int i = 0; i < elements.length; i++) { + IConfigurationElement configurationElement = elements[i]; + processProblem(configurationElement); + } + // process checkers + for (int i = 0; i < elements.length; i++) { + IConfigurationElement configurationElement = elements[i]; + processChecker(configurationElement); + } + // init parameters for checkers with parameters + for (Iterator iterator = problemList.keySet().iterator(); iterator + .hasNext();) { + IChecker c = iterator.next(); + if (c instanceof ICheckerWithPreferences) { + Collection list = problemList.get(c); + for (Iterator iterator2 = list.iterator(); iterator2 + .hasNext();) { + IProblem p = iterator2.next(); + if (p instanceof IProblemWorkingCopy) { + try { + ((ICheckerWithPreferences) c) + .initPreferences((IProblemWorkingCopy) p); + } catch (Throwable t) { + t.printStackTrace(); + CodanCorePlugin.log(t); + } + } + } + } + } + } + + /** + * @param configurationElement + */ + private void processCategories(IConfigurationElement configurationElement) { + if (configurationElement.getName().equals(CATEGORY_ELEMENT)) { + String id = getAtt(configurationElement, ID_ATTR); + if (id == null) + return; + String name = getAtt(configurationElement, NAME_ATTR); + if (name == null) + return; + CodanProblemCategory cat = new CodanProblemCategory(id, name); + String category = getAtt(configurationElement, + "parentCategory", false); //$NON-NLS-1$ + addCategory(cat, category); + } + } + + /** + * @param configurationElement + */ + private void processChecker(IConfigurationElement configurationElement) { + try { + if (configurationElement.getName().equals(CHECKER_ELEMENT)) { + String id = getAtt(configurationElement, ID_ATTR); + if (id == null) + return; + String name = getAtt(configurationElement, NAME_ATTR, false); + if (name == null) + name = id; + IChecker checkerObj = null; + try { + Object checker = configurationElement + .createExecutableExtension("class"); //$NON-NLS-1$ + checkerObj = (IChecker) checker; + addChecker(checkerObj); + } catch (CoreException e) { + CodanCorePlugin.log(e); + return; + } + IConfigurationElement[] children1 = configurationElement + .getChildren("problemRef"); //$NON-NLS-1$ + boolean hasRef = false; + IConfigurationElement[] children2 = configurationElement + .getChildren(PROBLEM_ELEMENT); + if (children2 != null) { + for (IConfigurationElement ref : children2) { + IProblem p = processProblem(ref); + addRefProblem(checkerObj, p); + hasRef = true; + } + } + if (children1 != null) { + for (IConfigurationElement ref : children1) { + hasRef = true; + IProblem p = getDefaultProfile().findProblem( + ref.getAttribute("refId")); //$NON-NLS-1$ + addRefProblem(checkerObj, p); + } + } + if (!hasRef) { + CodanProblem p = new CodanProblem(id, name); + addProblem(p, null); + addRefProblem(checkerObj, p); + } + } + } catch (Throwable e) { + CodanCorePlugin.log(e); + } + } + + /** + * @param configurationElement + * @return + */ + private CodanProblem processProblem( + IConfigurationElement configurationElement) { + if (configurationElement.getName().equals(PROBLEM_ELEMENT)) { + String id = getAtt(configurationElement, ID_ATTR); + if (id == null) + return null; + String name = getAtt(configurationElement, NAME_ATTR); + if (name == null) + name = id; + CodanProblem p = new CodanProblem(id, name); + String category = getAtt(configurationElement, "category", false); //$NON-NLS-1$ + if (category == null) + category = "org.eclipse.cdt.codan.core.categories.ProgrammingProblems"; //$NON-NLS-1$ + String enab = getAtt(configurationElement, "defaultEnabled", false); //$NON-NLS-1$ + String sev = getAtt(configurationElement, "defaultSeverity", false); //$NON-NLS-1$ + String patt = getAtt(configurationElement, "messagePattern", false); //$NON-NLS-1$ + String desc = getAtt(configurationElement, "description", false); //$NON-NLS-1$ + String markerType = getAtt(configurationElement, + "markerType", false); //$NON-NLS-1$ + if (enab != null) { + p.setEnabled(Boolean.valueOf(enab)); + } + if (sev != null) { + CodanSeverity cSev = CodanSeverity.valueOf(sev); + if (cSev != null) + p.setSeverity(cSev); + } + if (patt != null) { + p.setMessagePattern(patt); + } + if (markerType != null) { + p.setMarkerType(markerType); + } + p.setDescription(desc); + addProblem(p, category); + return p; + } + return null; + } + + private static String getAtt(IConfigurationElement configurationElement, + String name) { + return getAtt(configurationElement, name, true); + } + + private static String getAtt(IConfigurationElement configurationElement, + String name, boolean req) { + String elementValue = configurationElement.getAttribute(name); + if (elementValue == null && req) + CodanCorePlugin + .log("Extension " + configurationElement.getDeclaringExtension().getUniqueIdentifier() //$NON-NLS-1$ + + " missing required attribute: " + configurationElement.getName() + "." + name); //$NON-NLS-1$ //$NON-NLS-2$ + return elementValue; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.codan.core.model.ICheckersRegistry#iterator() + */ + public Iterator iterator() { + return checkers.iterator(); + } + + public static CheckersRegistry getInstance() { + if (instance == null) + return new CheckersRegistry(); + return instance; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.cdt.codan.core.model.ICheckersRegistry#addChecker(org.eclipse + * .cdt.codan.core.model.IChecker) + */ + public void addChecker(IChecker checker) { + checkers.add(checker); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.cdt.codan.core.model.ICheckersRegistry#addProblem(org.eclipse + * .cdt.codan.core.model.IProblem, java.lang.String) + */ + public void addProblem(IProblem p, String category) { + IProblemCategory cat = getDefaultProfile().findCategory(category); + if (cat == null) + cat = getDefaultProfile().getRoot(); + ((ProblemProfile) getDefaultProfile()).addProblem(p, cat); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.cdt.codan.core.model.ICheckersRegistry#addCategory(org.eclipse + * .cdt.codan.core.model.IProblemCategory, java.lang.String) + */ + public void addCategory(IProblemCategory p, String category) { + IProblemCategory cat = getDefaultProfile().findCategory(category); + if (cat == null) + cat = getDefaultProfile().getRoot(); + ((ProblemProfile) getDefaultProfile()).addCategory(p, cat); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.cdt.codan.core.model.ICheckersRegistry#addRefProblem(org. + * eclipse.cdt.codan.core.model.IChecker, + * org.eclipse.cdt.codan.core.model.IProblem) + */ + public void addRefProblem(IChecker c, IProblem p) { + Collection plist = problemList.get(c); + if (plist == null) { + plist = new ArrayList(); + problemList.put(c, plist); + } + plist.add(p); + } + + /** + * Returns list of problems registered for given checker + * + * @return collection of problems or null + */ + public Collection getRefProblems(IChecker checker) { + return problemList.get(checker); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.cdt.codan.core.model.ICheckersRegistry#getDefaultProfile() + */ + public IProblemProfile getDefaultProfile() { + return profiles.get(DEFAULT); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.cdt.codan.core.model.ICheckersRegistry#getWorkspaceProfile() + */ + public IProblemProfile getWorkspaceProfile() { + IProblemProfile wp = profiles.get(ResourcesPlugin.getWorkspace()); + if (wp == null) { + try { + wp = (IProblemProfile) getDefaultProfile().clone(); + // load default values + CodanPreferencesLoader loader = new CodanPreferencesLoader(wp); + loader.load(CodanPreferencesLoader.getWorkspaceNode()); + } catch (CloneNotSupportedException e) { + wp = getDefaultProfile(); + } + profiles.put(ResourcesPlugin.getWorkspace(), wp); + } + return wp; + } + + public void updateProfile(IResource element, IProblemProfile profile) { + // updating profile can invalidate all cached profiles + IProblemProfile defaultProfile = getDefaultProfile(); + profiles.clear(); + profiles.put(DEFAULT, defaultProfile); + if (profile != null && element != null) + profiles.put(element, profile); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.cdt.codan.core.model.ICheckersRegistry#getResourceProfile + * (org.eclipse.core.resources.IResource) + */ + public IProblemProfile getResourceProfile(IResource element) { + IProblemProfile prof = profiles.get(element); + if (prof == null) { + if (element instanceof IProject) { + try { + prof = (IProblemProfile) getWorkspaceProfile().clone(); + // load default values + CodanPreferencesLoader loader = new CodanPreferencesLoader( + prof); + Preferences projectNode = CodanPreferencesLoader + .getProjectNode((IProject) element); + boolean useWorkspace = projectNode.getBoolean( + PreferenceConstants.P_USE_PARENT, false); + if (!useWorkspace) { + loader.load(projectNode); + } + profiles.put(element, prof); + } catch (CloneNotSupportedException e) { + // cant + } + } else if (element.getParent() != null) { + prof = getResourceProfile(element.getParent()); + } else { + prof = getResourceProfile(element.getProject()); + } + } else { + } + return prof; + } + + /* + * (non-Javadoc) + * + * @seeorg.eclipse.cdt.codan.core.model.ICheckersRegistry# + * getResourceProfileWorkingCopy(org.eclipse.core.resources.IResource) + */ + public IProblemProfile getResourceProfileWorkingCopy(IResource element) { + try { + IProblemProfile prof = (IProblemProfile) getResourceProfile(element) + .clone(); + return prof; + } catch (CloneNotSupportedException e) { + // cant + return null; + } + } + + /** + * Test if checker is enabled (needs to be run) or not. Checker is enabled + * if at least one problem it prints is enabled. + * + * @param checker + * @param resource + * @return + */ + public boolean isCheckerEnabled(IChecker checker, IResource resource) { + IProblemProfile resourceProfile = getResourceProfile(resource); + Collection refProblems = getRefProblems(checker); + for (Iterator iterator = refProblems.iterator(); iterator + .hasNext();) { + IProblem p = iterator.next(); + // we need to check problem enablement in particular profile + IProblem problem = resourceProfile.findProblem(p.getId()); + if (problem == null) + throw new IllegalArgumentException("Id is not registered"); //$NON-NLS-1$ + if (problem.isEnabled()) + return true; + } + // no problem is enabled for this checker, skip the checker + return false; + } + + /** + * @return + */ + public int getCheckersSize() { + return checkers.size(); + } +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanApplication.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanApplication.java new file mode 100644 index 0000000..188be3c --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanApplication.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * Copyright (c) 2010 Alena Laskavaia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.internal.core; + +import java.util.ArrayList; +import java.util.Collection; + +import org.eclipse.cdt.codan.core.CodanRuntime; +import org.eclipse.cdt.codan.core.Messages; +import org.eclipse.cdt.codan.internal.core.model.CodanMarkerProblemReporter; +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.NullProgressMonitor; +import org.eclipse.equinox.app.IApplication; +import org.eclipse.equinox.app.IApplicationContext; +import org.eclipse.osgi.util.NLS; + +/** + * Application to support headless build + * + * @noextend This class is not intended to be extended by clients. + * @noinstantiate This class is not intended to be instantiated by clients. + */ +public class CodanApplication implements IApplication { + private Collection projects = new ArrayList(); + private boolean verbose = false; + private boolean all = false; + + public Object start(IApplicationContext context) throws Exception { + String[] args = (String[]) context.getArguments().get( + "application.args"); //$NON-NLS-1$ + if (args == null || args.length == 0) { + help(); + return EXIT_OK; + } + extractArguments(args); + CodanBuilder codanBuilder = new CodanBuilder(); + CodanRuntime runtime = CodanRuntime.getInstance(); + runtime.setProblemReporter(new CodanMarkerProblemReporter() { + @Override + public void reportProblem(String id, String markerType, + int severity, IResource file, int lineNumber, + int startChar, int endChar, String message) { + System.out.println(file.getLocation() + ":" + lineNumber + ": " //$NON-NLS-1$ //$NON-NLS-2$ + + message); + } + }); + IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); + if (all) { + log(Messages.CodanApplication_LogRunWorkspace); + codanBuilder.processResource(root, new NullProgressMonitor()); + } else { + for (String project : projects) { + log(Messages.CodanApplication_LogRunProject + project); + IProject wProject = root.getProject(project); + if (!wProject.exists()) { + System.err + .println( // + NLS.bind( + Messages.CodanApplication_Error_ProjectDoesNotExists, + project)); + continue; + } + codanBuilder.processResource(wProject, + new NullProgressMonitor()); + } + } + return EXIT_OK; + } + + /** + * @param string + */ + private void log(String string) { + if (verbose) + System.err.println(string); + } + + /** + * @param args + */ + private void extractArguments(String[] args) { + for (int i = 0; i < args.length; i++) { + String string = args[i]; + if (string.equals("-verbose")) { //$NON-NLS-1$ + verbose = true; + } else if (string.equals("-all")) { //$NON-NLS-1$ + all = true; + } else { + projects.add(string); + } + } + } + + /** + * + */ + private void help() { + System.out.println(Messages.CodanApplication_Usage); + System.out.println(Messages.CodanApplication_Options); + System.out.println(Messages.CodanApplication_all_option); + System.out.println(Messages.CodanApplication_verbose_option); + } + + public void stop() { + // nothing + } +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanBuilder.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanBuilder.java index 56916b8..6685b98 100644 --- a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanBuilder.java +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanBuilder.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Alena Laskavaia + * Copyright (c) 2009, 2010 Alena Laskavaia * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,91 +10,74 @@ *******************************************************************************/ package org.eclipse.cdt.codan.internal.core; -import java.io.File; -import java.net.URI; -import java.util.Collection; -import java.util.Iterator; import java.util.Map; import org.eclipse.cdt.codan.core.CodanCorePlugin; import org.eclipse.cdt.codan.core.CodanRuntime; -import org.eclipse.cdt.codan.core.model.ICAstChecker; +import org.eclipse.cdt.codan.core.Messages; import org.eclipse.cdt.codan.core.model.IChecker; -import org.eclipse.cdt.codan.core.model.ICodanAstReconciler; import org.eclipse.cdt.codan.core.model.ICodanBuilder; -import org.eclipse.cdt.codan.core.model.IProblem; -import org.eclipse.cdt.codan.core.model.IProblemProfile; import org.eclipse.cdt.codan.core.model.IProblemReporter; -import org.eclipse.cdt.codan.internal.core.model.CodanMarkerProblemReporter; -import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; -import org.eclipse.core.resources.IFile; +import org.eclipse.cdt.codan.core.model.IProblemReporterPersistent; +import org.eclipse.cdt.codan.core.model.IRunnableInEditorChecker; +import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.resources.IResourceDeltaVisitor; -import org.eclipse.core.resources.IResourceVisitor; -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.IncrementalProjectBuilder; -import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.SubProgressMonitor; +/** + * Implementation of {@link ICodanBuilder} + */ public class CodanBuilder extends IncrementalProjectBuilder implements - ICodanBuilder, ICodanAstReconciler { - public static final String BUILDER_ID = "org.eclipse.cdt.codan.core.codanBuilder"; + ICodanBuilder { + /** + * codan builder id + */ + public static final String BUILDER_ID = "org.eclipse.cdt.codan.core.codanBuilder"; //$NON-NLS-1$ - public class CodanDeltaVisitor implements IResourceDeltaVisitor { - /* - * (non-Javadoc) - * - * @see - * org.eclipse.core.resources.IResourceDeltaVisitor#visit(org.eclipse - * .core.resources.IResourceDelta) - */ - /* - * (non-Javadoc) - * - * @see - * org.eclipse.cdt.codan.internal.core.ICodanBuilder#visit(org.eclipse - * .core.resources.IResourceDelta) + private class CodanDeltaVisitor implements IResourceDeltaVisitor { + private IProgressMonitor monitor; + + /** + * @param monitor */ + public CodanDeltaVisitor(IProgressMonitor monitor) { + this.monitor = monitor; + } + public boolean visit(IResourceDelta delta) throws CoreException { IResource resource = delta.getResource(); switch (delta.getKind()) { - case IResourceDelta.ADDED: - // handle added resource - processResource(resource, new NullProgressMonitor()); - break; - case IResourceDelta.REMOVED: - // handle removed resource - break; - case IResourceDelta.CHANGED: - // handle changed resource - processResource(resource, new NullProgressMonitor()); - break; + case IResourceDelta.ADDED: + // handle added resource + processResource(resource, monitor); + break; + case IResourceDelta.REMOVED: + // handle removed resource + break; + case IResourceDelta.CHANGED: + // handle changed resource + processResource(resource, monitor); + break; } // return true to continue visiting children. return true; } } - public class CodanResourceVisitor implements IResourceVisitor { - public boolean visit(IResource resource) { - if (!(resource instanceof IProject)) - processResource(resource, new NullProgressMonitor()); - // return true to continue visiting children. - return true; - } - } - /* * (non-Javadoc) * * @see org.eclipse.core.internal.events.InternalBuilder#build(int, * java.util.Map, org.eclipse.core.runtime.IProgressMonitor) */ + @SuppressWarnings("rawtypes") + @Override protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException { if (kind == FULL_BUILD) { @@ -111,119 +94,101 @@ public class CodanBuilder extends IncrementalProjectBuilder implements } public void processResource(IResource resource, IProgressMonitor monitor) { - // String string = Platform.getPreferencesService().getString( - // CodanCorePlugin.PLUGIN_ID, "problems", "", null); - // System.err.println("set = " + string); - // delete general markers - IProblemReporter problemReporter = CodanRuntime.getInstance() - .getProblemReporter(); - if (problemReporter instanceof CodanMarkerProblemReporter) { - ((CodanMarkerProblemReporter) problemReporter) - .deleteMarkers(resource); - } - for (IChecker checker : CheckersRegisry.getInstance()) { - try { - boolean run = false; - if (checker.enabledInContext(resource)) - run = true; - if (areProblemsForCheckerEnabled(checker, resource)) - run = true; - if (run) - checker.processResource(resource); - } catch (Throwable e) { - CodanCorePlugin.log(e); - } - } - if (resource instanceof IProject) { + processResource(resource, monitor, null, false); + } + + protected void processResource(IResource resource, + IProgressMonitor monitor, Object model, boolean inEditor) { + CheckersRegistry chegistry = CheckersRegistry.getInstance(); + int checkers = chegistry.getCheckersSize(); + int memsize = 0; + if (resource instanceof IContainer) { try { - resource.accept(getResourceVisitor()); + IResource[] members = ((IContainer) resource).members(); + memsize = members.length; } catch (CoreException e) { CodanCorePlugin.log(e); } } - } - - public void reconcileAst(IASTTranslationUnit ast, IProgressMonitor monitor) { - if (ast == null) - return; - String filePath = ast.getFilePath(); - IWorkspace workspace = ResourcesPlugin.getWorkspace(); - IWorkspaceRoot root = workspace.getRoot(); - IFile[] resources; - URI uri = new File(filePath).toURI(); - resources = root.findFilesForLocationURI(uri); - if (resources != null && resources.length > 0) { - IFile resource = resources[0]; + int tick = 1000; + // System.err.println("processing " + resource); + monitor.beginTask(Messages.CodanBuilder_Code_Analysis_On + resource, + checkers + memsize * tick); + try { IProblemReporter problemReporter = CodanRuntime.getInstance() .getProblemReporter(); - // TODO: this is wrong - should not delete all markers - - // only those that contributed by the checker that we run now - if (problemReporter instanceof CodanMarkerProblemReporter) { - ((CodanMarkerProblemReporter) problemReporter) - .deleteMarkers(resource); - } - for (IChecker checker : CheckersRegisry.getInstance()) { + for (IChecker checker : chegistry) { try { - boolean run = false; - if (checker.enabledInContext(resource)) - run = true; - if (areProblemsForCheckerEnabled(checker, resource)) { - run = true; + if (monitor.isCanceled()) + return; + if (checker.enabledInContext(resource)) { + // delete markers if checker can possibly run on this + // resource + // this way if checker is not enabled markers would be + // deleted too + if (problemReporter instanceof IProblemReporterPersistent) { + // delete general markers + ((IProblemReporterPersistent) problemReporter) + .deleteProblems(resource, checker); + } + if (chegistry.isCheckerEnabled(checker, resource)) { + if (inEditor) { + if (checker.runInEditor() + && checker instanceof IRunnableInEditorChecker) { + ((IRunnableInEditorChecker) checker) + .processModel(model); + } + } else { + checker.processResource(resource); + } + } } - if (run && checker instanceof ICAstChecker - && checker.runInEditor()) - ((ICAstChecker) checker).processAst(ast); + monitor.worked(1); } catch (Throwable e) { CodanCorePlugin.log(e); } } + if (resource instanceof IContainer) { + try { + IResource[] members = ((IContainer) resource).members(); + for (int i = 0; i < members.length; i++) { + if (monitor.isCanceled()) + return; + IResource member = members[i]; + processResource(member, new SubProgressMonitor(monitor, + tick)); + } + } catch (CoreException e) { + CodanCorePlugin.log(e); + } + } + } finally { + monitor.done(); } } - /** - * @param checker - * @param resource - * @return - */ - private boolean areProblemsForCheckerEnabled(IChecker checker, - IResource resource) { - IProblemProfile resourceProfile = CheckersRegisry.getInstance() - .getResourceProfile(resource); - Collection refProblems = CheckersRegisry.getInstance() - .getRefProblems(checker); - for (Iterator iterator = refProblems.iterator(); iterator.hasNext();) { - IProblem p = (IProblem) iterator.next(); - // we need to check problem enablement in particular profile - IProblem problem = resourceProfile.findProblem(p.getId()); - if (problem == null) - throw new IllegalArgumentException("Id is not registered"); - if (problem.isEnabled()) - return true; - } - // no problem is enabled for this checker, skip the checker - return false; - } - protected void fullBuild(final IProgressMonitor monitor) throws CoreException { - try { - getProject().accept(new CodanResourceVisitor()); - } catch (CoreException e) { - } + processResource(getProject(), monitor); } protected void incrementalBuild(IResourceDelta delta, IProgressMonitor monitor) throws CoreException { // the visitor does the work. - delta.accept(new CodanDeltaVisitor()); + delta.accept(new CodanDeltaVisitor(monitor)); } - /* - * (non-Javadoc) + /** + * Run all checkers that support "check as you type" mode * - * @see org.eclipse.cdt.codan.core.model.ICodanBuilder#getResourceVisitor() + * @param model - model of given resource such as ast + * @param resource - resource to process + * @param monitor - progress monitor */ - public CodanResourceVisitor getResourceVisitor() { - return new CodanResourceVisitor(); + public void runInEditor(Object model, IResource resource, + IProgressMonitor monitor) { + if (model == null) + return; + processResource(resource, monitor, model, true); } } diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanPreferencesLoader.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanPreferencesLoader.java index bafff9a..38af027 100644 --- a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanPreferencesLoader.java +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanPreferencesLoader.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Alena Laskavaia + * Copyright (c) 2009, 2010 Alena Laskavaia * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,38 +10,50 @@ *******************************************************************************/ package org.eclipse.cdt.codan.internal.core; +import org.eclipse.cdt.codan.core.CodanCorePlugin; import org.eclipse.cdt.codan.core.model.CodanSeverity; import org.eclipse.cdt.codan.core.model.IProblem; import org.eclipse.cdt.codan.core.model.IProblemProfile; -import org.eclipse.cdt.codan.internal.core.model.CodanProblem; -import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.cdt.codan.core.model.IProblemWorkingCopy; +import org.eclipse.cdt.codan.core.param.IProblemPreference; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ProjectScope; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.osgi.service.prefs.Preferences; /** - * @author Alena + * Helper class to load/save problem profile settings in persistent storage * */ public class CodanPreferencesLoader { private IProblemProfile baseModel; /** - * @param workspaceProfile + * Constructor + * + * @param profile - problem profile to work with */ public CodanPreferencesLoader(IProblemProfile profile) { setInput(profile); } /** - * + * Default constructor */ public CodanPreferencesLoader() { } - public void setInput(Object model) { - baseModel = (IProblemProfile) model; + /** + * Sets the profile for this class + * + * @param profile + */ + public void setInput(IProblemProfile profile) { + baseModel = profile; } /** - * @return + * @return problems array from the profile */ public IProblem[] getProblems() { IProblem[] problems = baseModel.getProblems(); @@ -54,66 +66,144 @@ public class CodanPreferencesLoader { */ public void setProperty(String id, String s) { IProblem prob = baseModel.findProblem(id); - if (!(prob instanceof CodanProblem)) + if (!(prob instanceof IProblemWorkingCopy)) return; String sevs = s; boolean enabled = true; - if (sevs.startsWith("-")) { + if (sevs.startsWith("-")) { //$NON-NLS-1$ sevs = sevs.substring(1); enabled = false; } - ((CodanProblem) prob).setEnabled(enabled); + ((IProblemWorkingCopy) prob).setEnabled(enabled); CodanSeverity sev; try { sev = CodanSeverity.valueOf(sevs); } catch (RuntimeException e) { sev = CodanSeverity.Warning; } - ((CodanProblem) prob).setSeverity(sev); + ((IProblemWorkingCopy) prob).setSeverity(sev); } - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ @Override public String toString() { return getInput().toString(); } /** - * @return + * @return problem profile set for this class */ public IProblemProfile getInput() { return baseModel; } /** - * @param id - * @return + * @param id - property id, which is the same as problem id + * @return get text representation of a "property" value for the given id, + * which is severity name, with "-" in front of it it problem is + * disabled. */ public String getProperty(String id) { IProblem prob = baseModel.findProblem(id); - if (!(prob instanceof CodanProblem)) - return null; - String enabled = prob.isEnabled() ? "" : "-"; + String enabled = prob.isEnabled() ? "" : "-"; //$NON-NLS-1$ //$NON-NLS-2$ String severity = prob.getSeverity().toString(); String res = enabled + severity; return res; } /** + * Takes string values from storePreferences and applies them to the problem + * profile + * * @param storePreferences */ - public void load(IEclipsePreferences storePreferences) { + public void load(Preferences storePreferences) { IProblem[] probs = getProblems(); for (int i = 0; i < probs.length; i++) { String id = probs[i].getId(); String s = storePreferences.get(id, null); if (s != null) { setProperty(id, s); + setProblemPreferenceValues(id, storePreferences); } } } + + /** + * Takes string values of the problem preferences from storePreferences + * and applies them to the problem profile + * + * @param problemId + * @param storePreferences + */ + private void setProblemPreferenceValues(String problemId, + Preferences storePreferences) { + IProblem prob = baseModel.findProblem(problemId); + String prefKey = getPreferencesKey(problemId); + if (prefKey == null) + return; + String exported = storePreferences.get(prefKey, null); + if (exported != null) { + //System.err.println(prefKey + " import " + exported); + prob.getPreference().importValue(exported); + } + } + + /** + * Return preference node (osgi preferences) for the project + * + * @param project + * @return project preferences node + */ + public static Preferences getProjectNode(IProject project) { + if (!project.exists()) + return null; + Preferences prefNode = new ProjectScope(project) + .getNode(CodanCorePlugin.PLUGIN_ID); + if (prefNode == null) + return null; + return prefNode; + } + + /** + * Return preference node (osgi preferences) for the workspace + * + * @return project preferences node + */ + public static Preferences getWorkspaceNode() { + Preferences prefNode = new InstanceScope() + .getNode(CodanCorePlugin.PLUGIN_ID); + if (prefNode == null) + return null; + return prefNode; + } + + /** + * Name of the preference key for the root problem preference in the osgi + * preferences + * + * @param id - problem id + * @return top level preference id + */ + public String getPreferencesKey(String id) { + IProblem prob = baseModel.findProblem(id); + IProblemPreference pref = prob.getPreference(); + if (pref == null) + return null; + return id + "." + pref.getKey(); //$NON-NLS-1$ + } + + /** + * @param id - problem id + * @return - export value of root problem preference (to be saved in eclipse + * preferences) + */ + public String getPreferencesString(String id) { + IProblem prob = baseModel.findProblem(id); + IProblemPreference pref = prob.getPreference(); + if (pref == null) + return null; + String str = pref.exportValue(); + //System.err.println(id + " set " + str); + return str; + } } diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodeAnlysisNature.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodeAnlysisNature.java index 5157e16..f73ee61 100644 --- a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodeAnlysisNature.java +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodeAnlysisNature.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Alena Laskavaia + * Copyright (c) 2009, 2010 Alena Laskavaia * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -16,18 +16,16 @@ import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IProjectNature; import org.eclipse.core.runtime.CoreException; +/** + * Code Analysis Nature for builder + */ public class CodeAnlysisNature implements IProjectNature { /** * ID of this project nature */ - public static final String NATURE_ID = "org.eclipse.cdt.codan.core.codanNature"; + public static final String NATURE_ID = "org.eclipse.cdt.codan.core.codanNature"; //$NON-NLS-1$ private IProject project; - /* - * (non-Javadoc) - * - * @see org.eclipse.core.resources.IProjectNature#configure() - */ public void configure() throws CoreException { IProjectDescription desc = project.getDescription(); ICommand[] commands = desc.getBuildSpec(); @@ -45,11 +43,6 @@ public class CodeAnlysisNature implements IProjectNature { project.setDescription(desc, null); } - /* - * (non-Javadoc) - * - * @see org.eclipse.core.resources.IProjectNature#deconfigure() - */ public void deconfigure() throws CoreException { IProjectDescription description = getProject().getDescription(); ICommand[] commands = description.getBuildSpec(); @@ -66,22 +59,10 @@ public class CodeAnlysisNature implements IProjectNature { } } - /* - * (non-Javadoc) - * - * @see org.eclipse.core.resources.IProjectNature#getProject() - */ public IProject getProject() { return project; } - /* - * (non-Javadoc) - * - * @see - * org.eclipse.core.resources.IProjectNature#setProject(org.eclipse.core - * .resources.IProject) - */ public void setProject(IProject project) { this.project = project; } diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/AbstractBasicBlock.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/AbstractBasicBlock.java new file mode 100644 index 0000000..15a191a --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/AbstractBasicBlock.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2010 Alena Laskavaia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.internal.core.cfg; + +import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock; +import org.eclipse.cdt.codan.core.model.cfg.ICfgData; + +/** + * Abstract Basic Block for control flow graph. + */ +public abstract class AbstractBasicBlock implements IBasicBlock, ICfgData { + /** + * Empty array of basic blocks + */ + public final static IBasicBlock[] EMPTY_LIST = new IBasicBlock[0]; + private Object data; + + public Object getData() { + return data; + } + + public void setData(Object data) { + this.data = data; + } + + /** + * Add a node to list of outgoing nodes of this node + * + * @param node - node to add + */ + public abstract void addOutgoing(IBasicBlock node); + + /** + * Add a node to list of incoming nodes of this node + * + * @param node - node to add + */ + public abstract void addIncoming(IBasicBlock node); + + /** + * @return toString for data object + */ + public String toStringData() { + if (getData() == null) + return "0x" + Integer.toHexString(System.identityHashCode(this)); //$NON-NLS-1$ + return getData().toString(); + } + + @Override + public String toString() { + return getClass().getSimpleName() + ": " + toStringData(); //$NON-NLS-1$ + } +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/AbstractSingleIncomingNode.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/AbstractSingleIncomingNode.java new file mode 100644 index 0000000..9054f2a --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/AbstractSingleIncomingNode.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2010 Alena Laskavaia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.internal.core.cfg; + +import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock; +import org.eclipse.cdt.codan.core.model.cfg.ISingleIncoming; + +/** + * Abstract node with one incoming arc (node) + * + */ +public abstract class AbstractSingleIncomingNode extends AbstractBasicBlock + implements ISingleIncoming { + private IBasicBlock prev; + + /** + * Default constructor + */ + public AbstractSingleIncomingNode() { + super(); + } + + public IBasicBlock[] getIncomingNodes() { + return new IBasicBlock[] { prev }; + } + + public int getIncomingSize() { + return 1; + } + + public IBasicBlock getIncoming() { + return prev; + } + + /** + * Sets the incoming node + * + * @param prev + */ + public void setIncoming(IBasicBlock prev) { + this.prev = prev; + } + + @Override + public void addIncoming(IBasicBlock node) { + setIncoming(node); + } +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/AbstractSingleOutgoingNode.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/AbstractSingleOutgoingNode.java new file mode 100644 index 0000000..e4f7fcf --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/AbstractSingleOutgoingNode.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2010 Alena Laskavaia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.internal.core.cfg; + +import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock; +import org.eclipse.cdt.codan.core.model.cfg.ISingleOutgoing; + +/** + * Abstract implementation of basic block with single outgoing arc (node) + * + */ +public abstract class AbstractSingleOutgoingNode extends AbstractBasicBlock + implements ISingleOutgoing { + private IBasicBlock next; + + /** + * Default constructor + */ + public AbstractSingleOutgoingNode() { + super(); + } + + public IBasicBlock[] getOutgoingNodes() { + return new IBasicBlock[] { next }; + } + + public int getOutgoingSize() { + return 1; + } + + public IBasicBlock getOutgoing() { + return next; + } + + /** + * Sets outgoing node + * + * @param node + */ + public void setOutgoing(IBasicBlock node) { + this.next = node; + } + + @Override + public void addOutgoing(IBasicBlock node) { + setOutgoing(node); + } +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/BranchNode.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/BranchNode.java new file mode 100644 index 0000000..ecd99e1 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/BranchNode.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Alena Laskavaia + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.internal.core.cfg; + +import org.eclipse.cdt.codan.core.model.cfg.IBranchNode; + +/** + * Branch node is a node with on incoming arc, one outgoing arc and a "string" + * label. Can be used to represent branches of if, switch and labelled + * statements. + */ +public class BranchNode extends PlainNode implements IBranchNode { + protected String label; + + protected BranchNode(String label) { + super(); + this.label = label; + } + + public String getLabel() { + return label; + } + + @Override + public String toStringData() { + return label; + } +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/CVS/Entries b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/CVS/Entries new file mode 100644 index 0000000..bd763ef --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/CVS/Entries @@ -0,0 +1,12 @@ +/AbstractBasicBlock.java/1.10/Thu Jun 3 17:01:52 2010//TCDT_7_0_0 +/AbstractSingleIncomingNode.java/1.6/Thu Jun 3 17:01:52 2010//TCDT_7_0_0 +/AbstractSingleOutgoingNode.java/1.6/Thu Jun 3 17:01:52 2010//TCDT_7_0_0 +/BranchNode.java/1.5/Thu Jun 3 17:01:52 2010//TCDT_7_0_0 +/ConnectorNode.java/1.7/Thu Jun 3 17:01:52 2010//TCDT_7_0_0 +/ControlFlowGraph.java/1.11/Thu Jun 3 17:01:52 2010//TCDT_7_0_0 +/DecisionNode.java/1.9/Thu Jun 3 17:01:52 2010//TCDT_7_0_0 +/ExitNode.java/1.6/Thu Jun 3 17:01:52 2010//TCDT_7_0_0 +/JumpNode.java/1.9/Thu Jun 3 17:01:52 2010//TCDT_7_0_0 +/NodeFactory.java/1.2/Thu Jun 3 17:01:52 2010//TCDT_7_0_0 +/PlainNode.java/1.8/Thu Jun 3 17:01:52 2010//TCDT_7_0_0 +/StartNode.java/1.8/Thu Jun 3 17:01:52 2010//TCDT_7_0_0 diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/CVS/Repository b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/CVS/Repository new file mode 100644 index 0000000..34bede2 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/CVS/Repository @@ -0,0 +1 @@ +org.eclipse.cdt/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/CVS/Root b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/CVS/Root new file mode 100644 index 0000000..04efa23 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@dev.eclipse.org:/cvsroot/tools diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/CVS/Tag b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/CVS/Tag new file mode 100644 index 0000000..49a449a --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/CVS/Tag @@ -0,0 +1 @@ +NCDT_7_0_0 diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/ConnectorNode.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/ConnectorNode.java new file mode 100644 index 0000000..7c91818 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/ConnectorNode.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Alena Laskavaia + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.internal.core.cfg; + +import java.util.ArrayList; + +import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock; +import org.eclipse.cdt.codan.core.model.cfg.IConnectorNode; +import org.eclipse.cdt.codan.core.model.cfg.IJumpNode; + +/** + * TODO: add description + */ +public class ConnectorNode extends AbstractSingleOutgoingNode implements + IConnectorNode { + protected ArrayList incoming = new ArrayList(2); + + protected ConnectorNode() { + super(); + } + + @Override + public void addIncoming(IBasicBlock node) { + incoming.add(node); + } + + /* + * (non-Javadoc) + * + * @seeorg.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock# + * getIncomingIterator() + */ + public IBasicBlock[] getIncomingNodes() { + return incoming.toArray(new IBasicBlock[incoming.size()]); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.codan.core.model.cfg.IBasicBlock#getIncomingSize () + */ + public int getIncomingSize() { + return incoming.size(); + } + + /* + * (non-Javadoc) + * + * @seeorg.eclipse.cdt.codan.provisional.core.model.cfg.IConnectorNode# + * hasBackwardIncoming() + */ + public boolean hasBackwardIncoming() { + for (IBasicBlock node : incoming) { + if (node instanceof IJumpNode) { + if (((IJumpNode) node).isBackwardArc()) + return true; + } + } + return false; + } +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/ControlFlowGraph.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/ControlFlowGraph.java new file mode 100644 index 0000000..8133e8c --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/ControlFlowGraph.java @@ -0,0 +1,147 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Alena Laskavaia + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.internal.core.cfg; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.List; + +import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock; +import org.eclipse.cdt.codan.core.model.cfg.IBranchNode; +import org.eclipse.cdt.codan.core.model.cfg.IConnectorNode; +import org.eclipse.cdt.codan.core.model.cfg.IControlFlowGraph; +import org.eclipse.cdt.codan.core.model.cfg.IDecisionNode; +import org.eclipse.cdt.codan.core.model.cfg.IExitNode; +import org.eclipse.cdt.codan.core.model.cfg.ISingleOutgoing; +import org.eclipse.cdt.codan.core.model.cfg.IStartNode; + +/** + * Implementation of control flow graph + */ +public class ControlFlowGraph implements IControlFlowGraph { + private List exitNodes; + private List deadNodes = new ArrayList(); + private IStartNode start; + + public ControlFlowGraph(IStartNode start, Collection exitNodes) { + setExitNodes(exitNodes); + this.start = start; + } + + public Iterator getExitNodeIterator() { + return exitNodes.iterator(); + } + + public int getExitNodeSize() { + return exitNodes.size(); + } + + public void setExitNodes(Collection exitNodes) { + if (this.exitNodes != null) + throw new IllegalArgumentException( + "Cannot modify already exiting connector"); //$NON-NLS-1$ + this.exitNodes = Collections.unmodifiableList(new ArrayList( + exitNodes)); + } + + public void setUnconnectedNodes(Collection nodes) { + this.deadNodes = Collections + .unmodifiableList(new ArrayList(nodes)); + } + + /* + * (non-Javadoc) + * + * @seeorg.eclipse.cdt.codan.provisional.core.model.cfg.IControlFlowGraph# + * getStartNode() + */ + public IStartNode getStartNode() { + return start; + } + + void setStartNode(IStartNode start) { + this.start = start; + } + + public void print(IBasicBlock node) { + System.out.println(node.getClass().getSimpleName() + ": " //$NON-NLS-1$ + + ((AbstractBasicBlock) node).toStringData()); + if (node instanceof IDecisionNode) { + // todo + IBasicBlock[] branches = ((IDecisionNode) node).getOutgoingNodes(); + for (int i = 0; i < branches.length; i++) { + IBasicBlock brNode = branches[i]; + System.out.println("{"); //$NON-NLS-1$ + print(brNode); + System.out.println("}"); //$NON-NLS-1$ + } + print(((IDecisionNode) node).getMergeNode()); + } else if (node instanceof ISingleOutgoing) { + IBasicBlock next = ((ISingleOutgoing) node).getOutgoing(); + if (!(next instanceof IConnectorNode && !(next instanceof IBranchNode))) + print(next); + } + } + + /* + * (non-Javadoc) + * + * @seeorg.eclipse.cdt.codan.provisional.core.model.cfg.IControlFlowGraph# + * getUnconnectedNodeIterator() + */ + public Iterator getUnconnectedNodeIterator() { + return deadNodes.iterator(); + } + + /* + * (non-Javadoc) + * + * @seeorg.eclipse.cdt.codan.provisional.core.model.cfg.IControlFlowGraph# + * getUnconnectedNodeSize() + */ + public int getUnconnectedNodeSize() { + return deadNodes.size(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.codan.core.model.cfg.IControlFlowGraph#getNodes () + */ + public Collection getNodes() { + Collection result = new LinkedHashSet(); + getNodes(getStartNode(), result); + for (Iterator iterator = deadNodes.iterator(); iterator + .hasNext();) { + IBasicBlock d = iterator.next(); + getNodes(d, result); + } + return result; + } + + /** + * @param d + * @param result + */ + private void getNodes(IBasicBlock start, Collection result) { + if (result.contains(start)) + return; + result.add(start); + IBasicBlock[] outgoingNodes = start.getOutgoingNodes(); + for (int i = 0; i < outgoingNodes.length; i++) { + IBasicBlock b = outgoingNodes[i]; + getNodes(b, result); + } + } +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/DecisionNode.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/DecisionNode.java new file mode 100644 index 0000000..df0da9c --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/DecisionNode.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Alena Laskavaia + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.internal.core.cfg; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock; +import org.eclipse.cdt.codan.core.model.cfg.IBranchNode; +import org.eclipse.cdt.codan.core.model.cfg.IConnectorNode; +import org.eclipse.cdt.codan.core.model.cfg.IDecisionNode; + +/** + * @see {@link IDecisionNode} + */ +public class DecisionNode extends AbstractSingleIncomingNode implements + IDecisionNode { + private List next = new ArrayList(2); + private IConnectorNode conn; + + /** + * @param prev + */ + protected DecisionNode() { + super(); + } + + @Override + public void addOutgoing(IBasicBlock node) { + IBranchNode cnode = (IBranchNode) node; // cast to throw CCE + next.add(cnode); + } + + /* + * (non-Javadoc) + * + * @seeorg.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock# + * getOutgoingIterator() + */ + public IBasicBlock[] getOutgoingNodes() { + return next.toArray(new IBasicBlock[next.size()]); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.codan.core.model.cfg.IBasicBlock#getOutgoingSize () + */ + public int getOutgoingSize() { + return next.size(); + } + + /* + * (non-Javadoc) + * + * @seeorg.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionNode# + * getConnectionNode() + */ + public IConnectorNode getMergeNode() { + return conn; + } + + public void setMergeNode(IConnectorNode conn) { + this.conn = conn; + } +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/ExitNode.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/ExitNode.java new file mode 100644 index 0000000..7bd9848 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/ExitNode.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2010 Alena Laskavaia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.internal.core.cfg; + +import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock; +import org.eclipse.cdt.codan.core.model.cfg.IExitNode; +import org.eclipse.cdt.codan.core.model.cfg.IStartNode; + +/** + * Plain node has one prev one jump + * + */ +public class ExitNode extends AbstractSingleIncomingNode implements IExitNode { + private IStartNode start; + + protected ExitNode() { + super(); + } + + public IBasicBlock[] getOutgoingNodes() { + return EMPTY_LIST; + } + + public int getOutgoingSize() { + return 0; + } + + public IStartNode getStartNode() { + return start; + } + + public void setStartNode(IStartNode start) { + this.start = start; + } + + @Override + public void addOutgoing(IBasicBlock node) { + throw new UnsupportedOperationException(); + } +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/JumpNode.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/JumpNode.java new file mode 100644 index 0000000..b5198d0 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/JumpNode.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2010 Alena Laskavaia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.internal.core.cfg; + +import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock; +import org.eclipse.cdt.codan.core.model.cfg.IConnectorNode; +import org.eclipse.cdt.codan.core.model.cfg.IJumpNode; + +/** + * Jump node is node that connects unusual control pass, such as goto, break and + * continue + * + */ +public class JumpNode extends AbstractSingleIncomingNode implements IJumpNode { + private IConnectorNode jump; + private boolean backward; + + protected JumpNode() { + super(); + } + + public IBasicBlock[] getOutgoingNodes() { + return new IBasicBlock[] { jump }; + } + + public int getOutgoingSize() { + return 1; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.codan.core.model.cfg.IJumpNode#getJumpNode() + */ + public IConnectorNode getJumpNode() { + return jump; + } + + public IBasicBlock getOutgoing() { + return jump; + } + + public boolean isBackwardArc() { + return backward; + } + + public void setJump(IConnectorNode jump, boolean backward) { + if (this.jump != null && this.jump != jump) + throw new IllegalArgumentException( + "Cannot modify exiting connector"); //$NON-NLS-1$ + this.jump = jump; + this.backward = backward; + } + + public void setBackward(boolean backward) { + this.backward = backward; + } + + @Override + public void addOutgoing(IBasicBlock node) { + setJump((IConnectorNode) node, backward); + } +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/NodeFactory.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/NodeFactory.java new file mode 100644 index 0000000..0de0734 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/NodeFactory.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Alena Laskavaia + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.internal.core.cfg; + +import org.eclipse.cdt.codan.core.model.cfg.IBranchNode; +import org.eclipse.cdt.codan.core.model.cfg.IConnectorNode; +import org.eclipse.cdt.codan.core.model.cfg.IControlFlowGraph; +import org.eclipse.cdt.codan.core.model.cfg.IDecisionNode; +import org.eclipse.cdt.codan.core.model.cfg.IExitNode; +import org.eclipse.cdt.codan.core.model.cfg.IJumpNode; +import org.eclipse.cdt.codan.core.model.cfg.INodeFactory; +import org.eclipse.cdt.codan.core.model.cfg.IPlainNode; +import org.eclipse.cdt.codan.core.model.cfg.IStartNode; + +/** + * Factory that creates cfg nodes + */ +public class NodeFactory implements INodeFactory { + IControlFlowGraph graph; + + /* + * (non-Javadoc) + * + * @seeorg.eclipse.cdt.codan.provisional.core.model.cfg.INodeFactory# + * getControlFlowGraph() + */ + public IControlFlowGraph getControlFlowGraph() { + return graph; + } + + public NodeFactory() { + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.codan.core.model.cfg.INodeFactory#createPlainNode () + */ + public IPlainNode createPlainNode() { + return new PlainNode(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.codan.core.model.cfg.INodeFactory#createJumpNode () + */ + public IJumpNode createJumpNode() { + return new JumpNode(); + } + + /* + * (non-Javadoc) + * + * @seeorg.eclipse.cdt.codan.provisional.core.model.cfg.INodeFactory# + * createDecisionNode() + */ + public IDecisionNode createDecisionNode() { + return new DecisionNode(); + } + + /* + * (non-Javadoc) + * + * @seeorg.eclipse.cdt.codan.provisional.core.model.cfg.INodeFactory# + * createConnectiorNode() + */ + public IConnectorNode createConnectorNode() { + return new ConnectorNode(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.codan.core.model.cfg.INodeFactory#createStartNode () + */ + public IStartNode createStartNode() { + return new StartNode(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.codan.core.model.cfg.INodeFactory#createExitNode () + */ + public IExitNode createExitNode() { + return new ExitNode(); + } + + public IBranchNode createBranchNode(String label) { + return new BranchNode(label); + } +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/PlainNode.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/PlainNode.java new file mode 100644 index 0000000..d382fb4 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/PlainNode.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2010 Alena Laskavaia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.internal.core.cfg; + +import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock; +import org.eclipse.cdt.codan.core.model.cfg.IPlainNode; + +/** + * Plain node has one incoming arc and one outgoing arc + * + */ +public class PlainNode extends AbstractSingleIncomingNode implements IPlainNode { + protected IBasicBlock next; + + protected PlainNode() { + super(); + } + + public IBasicBlock[] getOutgoingNodes() { + return new IBasicBlock[] { next }; + } + + public int getOutgoingSize() { + return 1; + } + + public IBasicBlock getOutgoing() { + return next; + } + + public void setOutgoing(IBasicBlock exit) { + this.next = exit; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.cdt.codan.internal.core.cfg.AbstractBasicBlock#addOutgoing + * (org.eclipse.cdt.codan.core.model.cfg.IBasicBlock) + */ + @Override + public void addOutgoing(IBasicBlock node) { + setOutgoing(node); + } +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/StartNode.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/StartNode.java new file mode 100644 index 0000000..4d64bad --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/cfg/StartNode.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2010 Alena Laskavaia and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.internal.core.cfg; + +import org.eclipse.cdt.codan.core.model.cfg.IBasicBlock; +import org.eclipse.cdt.codan.core.model.cfg.IStartNode; + +/** + * Start node has no incoming, one outgoing and it is connect to function exits + * + */ +public class StartNode extends AbstractSingleOutgoingNode implements IStartNode { + protected StartNode() { + super(); + } + + public IBasicBlock[] getIncomingNodes() { + return EMPTY_LIST; + } + + public int getIncomingSize() { + return 0; + } + + @Override + public void addOutgoing(IBasicBlock node) { + setOutgoing(node); + } + + @Override + public void addIncoming(IBasicBlock node) { + throw new UnsupportedOperationException(); + } +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CVS/Entries b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CVS/Entries index 5f7a029..182ee54 100644 --- a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CVS/Entries +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CVS/Entries @@ -1,5 +1,6 @@ -/CodanMarkerProblemReporter.java/1.2/Wed Dec 16 21:48:48 2009// -/CodanProblem.java/1.1/Sat Aug 22 21:16:48 2009// -/CodanProblemCategory.java/1.2/Wed Dec 16 21:48:48 2009// -/ProblemProfile.java/1.1/Wed Sep 23 23:29:36 2009// -D +/CodanMarkerProblemReporter.java/1.15/Sun Jun 27 01:30:42 2010//TCDT_7_0_0 +/CodanProblem.java/1.9/Sun Jun 27 01:30:42 2010//TCDT_7_0_0 +/CodanProblemCategory.java/1.4/Sun Jun 27 01:30:42 2010//TCDT_7_0_0 +/CodanProblemLocation.java/1.4/Sun Jun 27 01:30:42 2010//TCDT_7_0_0 +/ProblemLocationFactory.java/1.3/Sun Jun 27 01:30:42 2010//TCDT_7_0_0 +/ProblemProfile.java/1.3/Sun Jun 27 01:30:42 2010//TCDT_7_0_0 diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CVS/Tag b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CVS/Tag new file mode 100644 index 0000000..49a449a --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CVS/Tag @@ -0,0 +1 @@ +NCDT_7_0_0 diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CodanMarkerProblemReporter.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CodanMarkerProblemReporter.java index a4599c5..51a4794 100644 --- a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CodanMarkerProblemReporter.java +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CodanMarkerProblemReporter.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Alena Laskavaia + * Copyright (c) 2009, 2010 Alena Laskavaia * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -11,39 +11,40 @@ package org.eclipse.cdt.codan.internal.core.model; import java.text.MessageFormat; +import java.util.Collection; +import java.util.Iterator; +import org.eclipse.cdt.codan.core.CodanCorePlugin; +import org.eclipse.cdt.codan.core.CodanRuntime; +import org.eclipse.cdt.codan.core.model.IChecker; +import org.eclipse.cdt.codan.core.model.ICheckersRegistry; import org.eclipse.cdt.codan.core.model.IProblem; import org.eclipse.cdt.codan.core.model.IProblemLocation; -import org.eclipse.cdt.codan.core.model.IProblemReporter; -import org.eclipse.cdt.codan.internal.core.CheckersRegisry; -import org.eclipse.core.resources.IFile; +import org.eclipse.cdt.codan.core.model.IProblemReporterPersistent; +import org.eclipse.cdt.codan.internal.core.CheckersRegistry; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; -public class CodanMarkerProblemReporter implements IProblemReporter { - - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.cdt.codan.core.model.IProblemReporter#reportProblem(java. - * lang.String, org.eclipse.cdt.codan.core.model.IProblemLocation, - * java.lang.Object[]) - */ +/** + * Problem reported that created eclipse markers + */ +public class CodanMarkerProblemReporter implements IProblemReporterPersistent { public void reportProblem(String id, IProblemLocation loc, Object... args) { - IFile file = loc.getFile(); + IResource file = loc.getFile(); int lineNumber = loc.getLineNumber(); if (file == null) - throw new NullPointerException("file"); + throw new NullPointerException("file"); //$NON-NLS-1$ if (id == null) - throw new NullPointerException("id"); - IProblem problem = CheckersRegisry.getInstance().getResourceProfile( - file).findProblem(id); + throw new NullPointerException("id"); //$NON-NLS-1$ + IProblem problem = CheckersRegistry.getInstance() + .getResourceProfile(file).findProblem(id); if (problem == null) - throw new IllegalArgumentException("Id is not registered"); + throw new IllegalArgumentException("Id is not registered:" + id); //$NON-NLS-1$ if (problem.isEnabled() == false) return; // skip int severity = problem.getSeverity().intValue(); @@ -53,25 +54,31 @@ public class CodanMarkerProblemReporter implements IProblemReporter { if (args != null && args.length > 0 && args[0] instanceof String) message = (String) args[0]; } else { - MessageFormat.format(messagePattern, args); + message = MessageFormat.format(messagePattern, args); } - reportProblem(id, severity, file, lineNumber, loc.getStartingChar(), - loc.getEndingChar(), message); + reportProblem(id, problem.getMarkerType(), severity, file, lineNumber, + loc.getStartingChar(), loc.getEndingChar(), message); } - /* - * (non-Javadoc) - * - * @see - * org.eclipse.cdt.codan.core.model.IProblemReporter#reportProblem(java. - * lang.String, org.eclipse.core.resources.IFile, int, java.lang.String) + /** + * @param id - problem id + * @param markerType - marker id + * @param severity - marker severity + * @param file - resource + * @param lineNumber - line number for error + * @param startChar - start char (offset in charts from the begging of the + * document) + * @param endChar - end char (offset in charts from the begging of the + * document, exclusive) + * @param message - marker message */ - public void reportProblem(String id, int severity, IFile file, - int lineNumber, int startChar, int endChar, String message) { + public void reportProblem(String id, String markerType, int severity, + IResource file, int lineNumber, int startChar, int endChar, + String message) { try { // Do not put in duplicates - IMarker[] cur = file.findMarkers(GENERIC_CODE_ANALYSIS_MARKER_TYPE, - false, IResource.DEPTH_ZERO); + IMarker[] cur = file.findMarkers(markerType, false, + IResource.DEPTH_ZERO); if (cur != null) { for (IMarker element : cur) { int line = ((Integer) element @@ -86,37 +93,72 @@ public class CodanMarkerProblemReporter implements IProblemReporter { } } } - IMarker marker = file - .createMarker(GENERIC_CODE_ANALYSIS_MARKER_TYPE); + IMarker marker = file.createMarker(markerType); marker.setAttribute(IMarker.MESSAGE, message); marker.setAttribute(IMarker.SEVERITY, severity); marker.setAttribute(IMarker.LINE_NUMBER, lineNumber); marker.setAttribute(IMarker.PROBLEM, id); marker.setAttribute(IMarker.CHAR_END, endChar); marker.setAttribute(IMarker.CHAR_START, startChar); + marker.setAttribute("org.eclipse.cdt.core.problem", 42); //$NON-NLS-1$ } catch (CoreException e) { e.printStackTrace(); } } - public void deleteMarkers(IResource file) { + public void deleteProblems(IResource file) { try { - file.deleteMarkers(GENERIC_CODE_ANALYSIS_MARKER_TYPE, false, + file.deleteMarkers(GENERIC_CODE_ANALYSIS_MARKER_TYPE, true, IResource.DEPTH_ZERO); } catch (CoreException ce) { ce.printStackTrace(); } } - public void deleteAllMarkers() { + public void deleteAllProblems() { try { - // TODO delete contributed markers too - ResourcesPlugin.getWorkspace().getRoot().deleteMarkers( - GENERIC_CODE_ANALYSIS_MARKER_TYPE, false, - IResource.DEPTH_INFINITE); + ResourcesPlugin + .getWorkspace() + .getRoot() + .deleteMarkers(GENERIC_CODE_ANALYSIS_MARKER_TYPE, true, + IResource.DEPTH_INFINITE); } catch (CoreException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + CodanCorePlugin.log(e); + } + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.cdt.codan.core.model.IProblemReporterPersistent#deleteProblems + * (org.eclipse.core.resources.IResource, + * org.eclipse.cdt.codan.core.model.IChecker) + */ + public void deleteProblems(final IResource file, final IChecker checker) { + try { + ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() { + public void run(IProgressMonitor monitor) throws CoreException { + IMarker[] markers = file.findMarkers( + GENERIC_CODE_ANALYSIS_MARKER_TYPE, true, + IResource.DEPTH_INFINITE); + ICheckersRegistry reg = CodanRuntime.getInstance() + .getChechersRegistry(); + for (int i = 0; i < markers.length; i++) { + IMarker m = markers[i]; + String id = m.getAttribute(IMarker.PROBLEM, ""); //$NON-NLS-1$ + Collection problems = reg.getRefProblems(checker); + for (Iterator iterator = problems.iterator(); iterator + .hasNext();) { + IProblem iProblem = iterator.next(); + if (iProblem.getId().equals(id)) + m.delete(); + } + } + } + }, null, IWorkspace.AVOID_UPDATE, null); + } catch (CoreException e) { + CodanCorePlugin.log(e); } } } diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CodanProblem.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CodanProblem.java index a094cc1..56b43c5 100644 --- a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CodanProblem.java +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CodanProblem.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Alena Laskavaia + * Copyright (c) 2009, 2010 Alena Laskavaia * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,20 +10,21 @@ *******************************************************************************/ package org.eclipse.cdt.codan.internal.core.model; -import java.util.Collection; -import java.util.HashMap; - import org.eclipse.cdt.codan.core.model.CodanSeverity; -import org.eclipse.cdt.codan.core.model.IProblem; -import org.eclipse.cdt.codan.core.model.IProblemCategory; +import org.eclipse.cdt.codan.core.model.IProblemReporter; +import org.eclipse.cdt.codan.core.model.IProblemWorkingCopy; +import org.eclipse.cdt.codan.core.param.IProblemPreference; -public class CodanProblem implements IProblem { +public class CodanProblem implements IProblemWorkingCopy { private String id; private String name; private String message; private CodanSeverity severity = CodanSeverity.Warning; private boolean enabled = true; - private HashMap properties = new HashMap(0); + private IProblemPreference preference; + private boolean frozen; + private String description; + private String markerType = IProblemReporter.GENERIC_CODE_ANALYSIS_MARKER_TYPE; public CodanSeverity getSeverity() { return severity; @@ -32,6 +33,7 @@ public class CodanProblem implements IProblem { public CodanProblem(String problemId, String name) { this.id = problemId; this.name = name; + this.frozen = false; } public String getName() { @@ -42,11 +44,6 @@ public class CodanProblem implements IProblem { return id; } - public IProblemCategory getCategory() { - // TODO Auto-generated method stub - return null; - } - @Override public String toString() { return name; @@ -73,19 +70,19 @@ public class CodanProblem implements IProblem { */ @Override public Object clone() throws CloneNotSupportedException { - return super.clone(); + CodanProblem prob = (CodanProblem) super.clone(); + if (preference != null) { + prob.preference = (IProblemPreference) preference.clone(); + } + return prob; } - public void setProperty(Object key, Object value) { - properties.put(key, value); + public void setPreference(IProblemPreference value) { + preference = value; } - public Object getProperty(Object key) { - return properties.get(key); - }; - - public Collection getPropertyKeys() { - return properties.keySet(); + public IProblemPreference getPreference() { + return preference; } /* @@ -97,10 +94,54 @@ public class CodanProblem implements IProblem { return message; } + protected void freeze() { + frozen = true; + } + /** - * @param message the message to set + * @param message + * the message to set */ public void setMessagePattern(String message) { + checkSet(); this.message = message; } + + protected void checkSet() { + if (frozen) + throw new IllegalStateException("Object is unmodifieble"); //$NON-NLS-1$ + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.codan.core.model.IProblem#getDescription() + */ + public String getDescription() { + return description; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.cdt.codan.core.model.IProblemWorkingCopy#setDescription(java + * .lang.String) + */ + public void setDescription(String desc) { + this.description = desc; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.codan.core.model.IProblem#getMarkerType() + */ + public String getMarkerType() { + return markerType; + } + + public void setMarkerType(String type) { + markerType = type; + } } diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CodanProblemCategory.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CodanProblemCategory.java index fc63480..0156211 100644 --- a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CodanProblemCategory.java +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CodanProblemCategory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Alena Laskavaia + * Copyright (c) 2009, 2010 Alena Laskavaia * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -41,40 +41,36 @@ public class CodanProblemCategory implements IProblemCategory, Cloneable { } public IProblemElement[] getChildren() { - return (IProblemElement[]) list.toArray(new IProblemElement[list.size()]); + return list.toArray(new IProblemElement[list.size()]); } public void addChild(IProblemElement p) { list.add(p); } - public IProblem findProblem(String id) { - Object[] children = this.getChildren(); + public static IProblem findProblem(IProblemCategory c, String id) { + Object[] children = c.getChildren(); for (Object object : children) { if (object instanceof IProblemCategory) { IProblemCategory cat = (IProblemCategory) object; - IProblem found = cat.findProblem(id); - if (found != null) - return found; + IProblem found = findProblem(cat, id); + if (found != null) return found; } else if (object instanceof IProblem) { IProblem p = (IProblem) object; - if (p.getId().equals(id)) - return p; + if (p.getId().equals(id)) return p; } } return null; } - public IProblemCategory findCategory(String id) { - if (getId().equals(id)) - return this; - Object[] children = getChildren(); + public static IProblemCategory findCategory(IProblemCategory cat, String id) { + if (cat.getId().equals(id)) return cat; + Object[] children = cat.getChildren(); for (Object object : children) { if (object instanceof IProblemCategory) { - IProblemCategory cat = (IProblemCategory) object; - IProblemCategory found = cat.findCategory(id); - if (found != null) - return found; + IProblemCategory cat2 = (IProblemCategory) object; + IProblemCategory found = findCategory(cat2, id); + if (found != null) return found; } } return null; @@ -90,8 +86,7 @@ public class CodanProblemCategory implements IProblemCategory, Cloneable { try { CodanProblemCategory clone = (CodanProblemCategory) super.clone(); clone.list = new ArrayList(); - for (Iterator iterator = this.list.iterator(); iterator - .hasNext();) { + for (Iterator iterator = this.list.iterator(); iterator.hasNext();) { IProblemElement child = iterator.next(); clone.list.add((IProblemElement) child.clone()); } diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CodanProblemLocation.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CodanProblemLocation.java new file mode 100644 index 0000000..ca6bd02 --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CodanProblemLocation.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Alena Laskavaia + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.internal.core.model; + +import org.eclipse.cdt.codan.core.model.AbstractProblemLocation; +import org.eclipse.core.resources.IFile; + +/** + * Codan Problem Location, so far same as abstract class + * + */ +public class CodanProblemLocation extends AbstractProblemLocation { + public CodanProblemLocation(IFile file, int startChar, int endChar) { + super(file, startChar, endChar); + } + + public CodanProblemLocation(IFile file, int startChar, int endChar, int line) { + super(file, startChar, endChar); + this.line = line; + } + + protected CodanProblemLocation(IFile file, int line) { + super(file, line); + } +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/ProblemLocationFactory.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/ProblemLocationFactory.java new file mode 100644 index 0000000..835f6bf --- /dev/null +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/ProblemLocationFactory.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 Alena Laskavaia + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alena Laskavaia - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.internal.core.model; + +import org.eclipse.cdt.codan.core.model.IProblemLocation; +import org.eclipse.cdt.codan.core.model.IProblemLocationFactory; +import org.eclipse.core.resources.IFile; + +/** + * Factory class that allows to create problem locations + * + */ +public class ProblemLocationFactory implements IProblemLocationFactory { + /* + * (non-Javadoc) + * + * @seeorg.eclipse.cdt.codan.core.model.IProblemLocationFactory# + * createProblemLocation(org.eclipse.core.resources.IFile, int) + */ + public IProblemLocation createProblemLocation(IFile file, int line) { + return new CodanProblemLocation(file, line); + } + + /* + * (non-Javadoc) + * + * @seeorg.eclipse.cdt.codan.core.model.IProblemLocationFactory# + * createProblemLocation(org.eclipse.core.resources.IFile, int, int) + */ + public IProblemLocation createProblemLocation(IFile file, int startChar, + int endChar) { + return new CodanProblemLocation(file, startChar, endChar); + } + + /* + * (non-Javadoc) + * + * @seeorg.eclipse.cdt.codan.core.model.IProblemLocationFactory# + * createProblemLocation(org.eclipse.core.resources.IFile, int, int, int) + */ + public IProblemLocation createProblemLocation(IFile file, int startChar, + int endChar, int line) { + return new CodanProblemLocation(file, startChar, endChar, line); + } +} diff --git a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/ProblemProfile.java b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/ProblemProfile.java index d2330f1..1eb045b 100644 --- a/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/ProblemProfile.java +++ b/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/ProblemProfile.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Alena Laskavaia + * Copyright (c) 2009, 2010 Alena Laskavaia * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -22,8 +22,7 @@ import org.eclipse.cdt.codan.core.model.IProblemProfile; * */ public class ProblemProfile implements IProblemProfile, Cloneable { - private IProblemCategory rootCategory = new CodanProblemCategory("root", - "root"); + private IProblemCategory rootCategory = new CodanProblemCategory("root", "root"); //$NON-NLS-1$ //$NON-NLS-2$ /* * (non-Javadoc) @@ -33,7 +32,7 @@ public class ProblemProfile implements IProblemProfile, Cloneable { * .String) */ public IProblem findProblem(String id) { - return getRoot().findProblem(id); + return CodanProblemCategory.findProblem(getRoot(), id); } /* @@ -51,8 +50,7 @@ public class ProblemProfile implements IProblemProfile, Cloneable { * @param root * @param problems */ - protected void collectProblems(IProblemCategory parent, - Collection problems) { + protected void collectProblems(IProblemCategory parent, Collection problems) { Object[] children = parent.getChildren(); for (Object object : children) { if (object instanceof IProblemCategory) { @@ -69,13 +67,12 @@ public class ProblemProfile implements IProblemProfile, Cloneable { } public void addProblem(IProblem p, IProblemCategory cat) { - if (cat == null) - cat = getRoot(); + if (cat == null) cat = getRoot(); ((CodanProblemCategory) cat).addChild(p); } public IProblemCategory findCategory(String id) { - return getRoot().findCategory(id); + return CodanProblemCategory.findCategory(getRoot(), id); } /* @@ -87,8 +84,7 @@ public class ProblemProfile implements IProblemProfile, Cloneable { public Object clone() { try { ProblemProfile clone = (ProblemProfile) super.clone(); - clone.rootCategory = (IProblemCategory) ((CodanProblemCategory) this.rootCategory) - .clone(); + clone.rootCategory = (IProblemCategory) ((CodanProblemCategory) this.rootCategory).clone(); return clone; } catch (CloneNotSupportedException e) { return this; -- cgit