### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java,v retrieving revision 1.64 diff -u -r1.64 SwitchStatement.java --- compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java 31 Jan 2006 11:19:01 -0000 1.64 +++ compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java 14 Feb 2006 15:26:30 -0000 @@ -32,6 +32,12 @@ public int caseCount; int[] constants; + // fallthrough + public final static int CASE = 0; + public final static int FALLTHROUGH = 1; + public final static int ESCAPING = 2; + + public SyntheticMethodBinding synthetic; // use for switch on enums types // for local variables table attributes @@ -57,20 +63,36 @@ int caseIndex = 0; if (statements != null) { boolean didAlreadyComplain = false; + int fallThroughState = CASE; for (int i = 0, max = statements.length; i < max; i++) { Statement statement = statements[i]; if ((caseIndex < caseCount) && (statement == cases[caseIndex])) { // statement is a case this.scope.enclosingCase = cases[caseIndex]; // record entering in a switch case block caseIndex++; + if (fallThroughState == FALLTHROUGH + && (statement.bits & ASTNode.DocumentedFallthrough) == 0) { // the case is not fall-through protected by a line comment + scope.problemReporter().possibleFallThroughCase(this.scope.enclosingCase); + } caseInits = caseInits.mergedWith(flowInfo.unconditionalInits()); didAlreadyComplain = false; // reset complaint + fallThroughState = CASE; } else if (statement == defaultCase) { // statement is the default case this.scope.enclosingCase = defaultCase; // record entering in a switch case block + if (fallThroughState == FALLTHROUGH + && (statement.bits & ASTNode.DocumentedFallthrough) == 0) { + scope.problemReporter().possibleFallThroughCase(this.scope.enclosingCase); + } caseInits = caseInits.mergedWith(flowInfo.unconditionalInits()); didAlreadyComplain = false; // reset complaint + fallThroughState = CASE; + } else { + fallThroughState = FALLTHROUGH; // reset below if needed } if (!statement.complainIfUnreachable(caseInits, scope, didAlreadyComplain)) { caseInits = statement.analyseCode(scope, switchContext, caseInits); + if (caseInits == FlowInfo.DEAD_END) { + fallThroughState = ESCAPING; + } } else { didAlreadyComplain = true; } Index: compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java,v retrieving revision 1.63 diff -u -r1.63 ASTNode.java --- compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java 31 Jan 2006 11:19:01 -0000 1.63 +++ compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java 14 Feb 2006 15:26:29 -0000 @@ -40,7 +40,7 @@ public final static int Bit16 = 0x8000; // in javadoc comment (name ref, type ref, msg) public final static int Bit17 = 0x10000; // compound assigned (reference lhs) public final static int Bit18 = 0x20000; // non null (expression) - public final static int Bit19 = 0x40000; + public final static int Bit19 = 0x40000; public final static int Bit20 = 0x80000; public final static int Bit21 = 0x100000; public final static int Bit22 = 0x200000; // parenthesis count (expression) @@ -51,7 +51,7 @@ public final static int Bit27 = 0x4000000; // parenthesis count (expression) public final static int Bit28 = 0x8000000; // parenthesis count (expression) public final static int Bit29 = 0x10000000; // parenthesis count (expression) - public final static int Bit30 = 0x20000000; // assignment with no effect (assignment) | elseif (if statement) | try block exit (try statement) + public final static int Bit30 = 0x20000000; // assignment with no effect (assignment) | elseif (if statement) | try block exit (try statement) | fall-through (case statement) public final static int Bit31 = 0x40000000; // local declaration reachable (local decl) | ignore raw type check (type ref) | discard entire assignment (assignment) public final static int Bit32 = 0x80000000; // reachable (statement) @@ -112,6 +112,7 @@ public static final int IsReachable = Bit32; public static final int IsLocalDeclarationReachable = Bit31; public static final int LabelUsed = Bit7; + public static final int DocumentedFallthrough = Bit30; // try statements public static final int IsSubRoutineEscaping = Bit15; Index: compiler/org/eclipse/jdt/core/compiler/IProblem.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java,v retrieving revision 1.170 diff -u -r1.170 IProblem.java --- compiler/org/eclipse/jdt/core/compiler/IProblem.java 13 Feb 2006 09:59:51 -0000 1.170 +++ compiler/org/eclipse/jdt/core/compiler/IProblem.java 14 Feb 2006 15:26:29 -0000 @@ -74,6 +74,7 @@ * InvalidDigit * IBM Corporation - added the following constants * ParameterAssignment + * FallthroughCase *******************************************************************************/ package org.eclipse.jdt.core.compiler; @@ -275,7 +276,8 @@ int DuplicateFinalLocalInitialization = Internal + 57; /** @since 2.1 */ int NonBlankFinalLocalAssignment = Internal + 58; - + /** @since 3.2 */ + int ParameterAssignment = Internal + 59; int FinalOuterLocalAssignment = Internal + 60; int LocalVariableIsNeverUsed = Internal + 61; int ArgumentIsNeverUsed = Internal + 62; @@ -289,8 +291,6 @@ int TooManyArrayDimensions = Internal + 68; /** @since 2.1 */ int BytecodeExceeds64KLimitForConstructor = Internal + 69; - /** @since 3.2 */ - int ParameterAssignment = Internal + 860; // fields int UndefinedField = FieldRelated + 70; @@ -406,6 +406,7 @@ // switch int IncorrectSwitchType = TypeRelated + 169; int DuplicateCase = FieldRelated + 170; + // labelled int DuplicateLabel = Internal + 171; int InvalidBreak = Internal + 172; @@ -449,6 +450,9 @@ int NeedToEmulateMethodAccess = MethodRelated + 192; int NeedToEmulateConstructorAccess = MethodRelated + 193; + /** @since 3.2 */ + int FallthroughCase = Internal + 194; + //inherited name hides enclosing name (sort of ambiguous) int InheritedMethodHidesEnclosingName = MethodRelated + 195; int InheritedFieldHidesEnclosingName = FieldRelated + 196; Index: batch/org/eclipse/jdt/internal/compiler/batch/messages.properties =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties,v retrieving revision 1.497 diff -u -r1.497 messages.properties --- batch/org/eclipse/jdt/internal/compiler/batch/messages.properties 13 Feb 2006 15:43:48 -0000 1.497 +++ batch/org/eclipse/jdt/internal/compiler/batch/messages.properties 14 Feb 2006 15:26:29 -0000 @@ -143,6 +143,7 @@ \ discouraged + use of types matching a discouraged access rule\n\ \ emptyBlock undocumented empty block\n\ \ enumSwitch incomplete enum switch\n\ +\ fallthrough possible fall-through case\n\ \ fieldHiding field hiding another variable\n\ \ finalBound type parameter with final bound\n\ \ finally + finally block not completing normally\n\ Index: batch/org/eclipse/jdt/internal/compiler/batch/Main.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java,v retrieving revision 1.230 diff -u -r1.230 Main.java --- batch/org/eclipse/jdt/internal/compiler/batch/Main.java 6 Feb 2006 02:00:53 -0000 1.230 +++ batch/org/eclipse/jdt/internal/compiler/batch/Main.java 14 Feb 2006 15:26:29 -0000 @@ -1962,6 +1962,10 @@ this.options.put( CompilerOptions.OPTION_ReportForbiddenReference, isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); + } else if (token.equals("fallthrough")) { //$NON-NLS-1$ + this.options.put( + CompilerOptions.OPTION_ReportFallthroughCase, + isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); } else { throw new InvalidInputException(Main.bind("configure.invalidWarning", token)); //$NON-NLS-1$ } Index: compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties,v retrieving revision 1.195 diff -u -r1.195 messages.properties --- compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties 8 Feb 2006 21:54:39 -0000 1.195 +++ compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties 14 Feb 2006 15:26:31 -0000 @@ -45,7 +45,7 @@ 56 = Duplicate parameter {0} 57 = The final local variable {0} may already have been assigned 58 = The final local variable {0} cannot be assigned. It must be blank and not using a compound assignment - +59 = The parameter {0} should not be assigned 60 = The final local variable {0} cannot be assigned, since it is defined in an enclosing type 61 = The local variable {0} is never read 62 = The parameter {0} is never read @@ -157,11 +157,11 @@ 187 = Unreachable catch block for {0}. It is already handled by the catch block for {1} 188 = Empty control-flow statement 189 = Statement unnecessarily nested within else clause. The corresponding then clause does not complete normally - 190 = Read access to enclosing field {0}.{1} is emulated by a synthetic accessor method. Increasing its visibility will improve your performance 191 = Write access to enclosing field {0}.{1} is emulated by a synthetic accessor method. Increasing its visibility will improve your performance 192 = Access to enclosing method {1}({2}) from the type {0} is emulated by a synthetic accessor method. Increasing its visibility will improve your performance 193 = Access to enclosing constructor {0}({1}) is emulated by a synthetic accessor method. Increasing its visibility will improve your performance +194 = Switch case may be entered by falling through previous case 195 = The method {1} is defined in an inherited type and an enclosing scope 196 = The field {0} is defined in an inherited type and an enclosing scope 197 = The type {0} is defined in an inherited type and an enclosing scope @@ -561,4 +561,3 @@ 858 = The parameterized constructor <{3}>{0}({1}) of type {2} is not applicable for the arguments ({4}) 859 = The constructor {0}({1}) of raw type {2} is no longer generic; it cannot be parameterized with arguments <{3}> -860 = The parameter {0} should not be assigned Index: compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java,v retrieving revision 1.290 diff -u -r1.290 ProblemReporter.java --- compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java 10 Feb 2006 13:47:55 -0000 1.290 +++ compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java 14 Feb 2006 15:26:31 -0000 @@ -1535,6 +1535,9 @@ case IProblem.ParameterAssignment: return CompilerOptions.ParameterAssignment; + + case IProblem.FallthroughCase: + return CompilerOptions.FallthroughCase; } return 0; } @@ -4927,6 +4930,14 @@ start, end); } +public void possibleFallThroughCase(CaseStatement caseStatement) { + this.handle( + IProblem.FallthroughCase, + NoArgument, + NoArgument, + caseStatement.sourceStart, + caseStatement.sourceEnd); +} public void possibleAccidentalBooleanAssignment(Assignment assignment) { this.handle( IProblem.PossibleAccidentalBooleanAssignment, Index: model/org/eclipse/jdt/core/JavaCore.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java,v retrieving revision 1.532 diff -u -r1.532 JavaCore.java --- model/org/eclipse/jdt/core/JavaCore.java 13 Feb 2006 15:43:48 -0000 1.532 +++ model/org/eclipse/jdt/core/JavaCore.java 14 Feb 2006 15:26:32 -0000 @@ -57,6 +57,7 @@ * IBM Corporation - added the following constants: * TIMEOUT_FOR_PARAMETER_NAME_FROM_ATTACHED_JAVADOC * IBM Corporation - added the following constants: + * COMPILER_PB_FALLTHROUGH_CASE * COMPILER_PB_PARAMETER_ASSIGNMENT * COMPILER_PB_NULL_REFERENCE * IBM Corporation - added the following constants: @@ -365,6 +366,12 @@ /** * Possible configurable option ID. * @see #getDefaultOptions() + * @since 3.2 + */ + public static final String COMPILER_PB_FALLTHROUGH_CASE = PLUGIN_ID + ".compiler.problem.fallthroughCase"; //$NON-NLS-1$ + /** + * Possible configurable option ID. + * @see #getDefaultOptions() * @since 3.0 */ public static final String COMPILER_PB_EMPTY_STATEMENT = PLUGIN_ID + ".compiler.problem.emptyStatement"; //$NON-NLS-1$ @@ -2271,6 +2278,13 @@ * - possible values: { "error", "warning", "ignore" } * - default: "ignore" * + * COMPILER / Reporting Switch Fall-Through Case + * When enabled, the compiler will issue an error or a warning if a case may be + * entered by falling through previous case. Empty cases are allowed. + * - option id: "org.eclipse.jdt.core.compiler.problem.fallthroughCase" + * - possible values: { "error", "warning", "ignore" } + * - default: "ignore" + * * BUILDER / Specifying Filters for Resource Copying Control * Allow to specify some filters to control the resource copy process. * - option id: "org.eclipse.jdt.core.builder.resourceCopyExclusionFilter" Index: compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java,v retrieving revision 1.160 diff -u -r1.160 CompilerOptions.java --- compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java 8 Feb 2006 10:47:46 -0000 1.160 +++ compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java 14 Feb 2006 15:26:30 -0000 @@ -104,6 +104,7 @@ public static final String OPTION_ReportUnusedLabel = "org.eclipse.jdt.core.compiler.problem.unusedLabel"; //$NON-NLS-1$ public static final String OPTION_FatalOptionalError = "org.eclipse.jdt.core.compiler.problem.fatalOptionalError"; //$NON-NLS-1$ public static final String OPTION_ReportParameterAssignment = "org.eclipse.jdt.core.compiler.problem.parameterAssignment"; //$NON-NLS-1$ + public static final String OPTION_ReportFallthroughCase = "org.eclipse.jdt.core.compiler.problem.fallthroughCase"; //$NON-NLS-1$ // Backward compatibility public static final String OPTION_ReportInvalidAnnotation = "org.eclipse.jdt.core.compiler.problem.invalidAnnotation"; //$NON-NLS-1$ @@ -187,6 +188,7 @@ public static final long RawTypeReference = ASTNode.Bit46L; public static final long UnusedLabel = ASTNode.Bit47L; public static final long ParameterAssignment = ASTNode.Bit48L; + public static final long FallthroughCase = ASTNode.Bit49L; // Default severity level for handlers public long errorThreshold = 0; @@ -381,7 +383,6 @@ optionsMap.put(OPTION_Source, versionFromJdkLevel(this.sourceLevel)); optionsMap.put(OPTION_TargetPlatform, versionFromJdkLevel(this.targetJDK)); optionsMap.put(OPTION_FatalOptionalError, this.treatOptionalErrorAsFatal ? ENABLED : DISABLED); - if (this.defaultEncoding != null) { optionsMap.put(OPTION_Encoding, this.defaultEncoding); } @@ -397,6 +398,7 @@ optionsMap.put(OPTION_SuppressWarnings, this.suppressWarnings ? ENABLED : DISABLED); optionsMap.put(OPTION_ReportUnhandledWarningToken, getSeverityString(UnhandledWarningToken)); optionsMap.put(OPTION_ReportParameterAssignment, getSeverityString(ParameterAssignment)); + optionsMap.put(OPTION_ReportFallthroughCase, getSeverityString(FallthroughCase)); return optionsMap; } @@ -638,6 +640,7 @@ if ((optionValue = optionsMap.get(OPTION_ReportUnhandledWarningToken)) != null) updateSeverity(UnhandledWarningToken, optionValue); if ((optionValue = optionsMap.get(OPTION_ReportUnusedLabel)) != null) updateSeverity(UnusedLabel, optionValue); if ((optionValue = optionsMap.get(OPTION_ReportParameterAssignment)) != null) updateSeverity(ParameterAssignment, optionValue); + if ((optionValue = optionsMap.get(OPTION_ReportFallthroughCase)) != null) updateSeverity(FallthroughCase, optionValue); // Javadoc options if ((optionValue = optionsMap.get(OPTION_DocCommentSupport)) != null) { @@ -867,6 +870,7 @@ OPTION_ReportDiscouragedReference, OPTION_ReportEmptyStatement, OPTION_ReportEnumIdentifier, + OPTION_ReportFallthroughCase, OPTION_ReportFieldHiding, OPTION_ReportFinalParameterBound, OPTION_ReportFinallyBlockNotCompletingNormally, @@ -962,6 +966,8 @@ return "restriction"; //$NON-NLS-1$ case (int) (NullReference >>> 32) : return "null"; //$NON-NLS-1$ + case (int) (FallthroughCase >>> 32) : + return "fallthrough"; //$NON-NLS-1$ } } return null; @@ -972,6 +978,7 @@ "boxing", //$NON-NLS-1$ "dep-ann", //$NON-NLS-1$ "deprecation", //$NON-NLS-1$ + "fall-through", //$NON-NLS-1$ "finally", //$NON-NLS-1$ "hiding", //$NON-NLS-1$ "incomplete-switch", //$NON-NLS-1$ @@ -1004,6 +1011,8 @@ return MissingDeprecatedAnnotation; break; case 'f' : + if ("fallthrough".equals(warningToken)) //$NON-NLS-1$ + return FallthroughCase; if ("finally".equals(warningToken)) //$NON-NLS-1$ return FinallyBlockNotCompleting; break;