### 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 13 Feb 2006 16:19:50 -0000 @@ -57,20 +57,43 @@ int caseIndex = 0; if (statements != null) { boolean didAlreadyComplain = false; + byte fallThroughState = 0; + // 0: start or reset + // 1: previous statement is a case + // 2: previous statement is a non fall-through statement + // 9: previous statement is a non case, fall-through statement 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 == 9 + && (statement.bits & ASTNode.Bit19) == 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 = 1; } else if (statement == defaultCase) { // statement is the default case this.scope.enclosingCase = defaultCase; // record entering in a switch case block + if (fallThroughState == 9 && (statement.bits & ASTNode.Bit19) == 0) { + scope.problemReporter().possibleFallThroughCase(this.scope.enclosingCase); + } caseInits = caseInits.mergedWith(flowInfo.unconditionalInits()); didAlreadyComplain = false; // reset complaint + fallThroughState = 1; + } + else { + fallThroughState = 0; // reset } if (!statement.complainIfUnreachable(caseInits, scope, didAlreadyComplain)) { caseInits = statement.analyseCode(scope, switchContext, caseInits); + if ((caseInits.tagBits & FlowInfo.UNREACHABLE) != 0) { + fallThroughState = 2; + } + else if (fallThroughState != 1) { + fallThroughState = 9; // non case, fall-through statement + } } 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 13 Feb 2006 16:19:49 -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; // fall-through protected (case statement) public final static int Bit20 = 0x80000; public final static int Bit21 = 0x100000; public final static int Bit22 = 0x200000; // parenthesis count (expression) 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.169 diff -u -r1.169 IProblem.java --- compiler/org/eclipse/jdt/core/compiler/IProblem.java 3 Feb 2006 18:37:53 -0000 1.169 +++ compiler/org/eclipse/jdt/core/compiler/IProblem.java 13 Feb 2006 16:19:49 -0000 @@ -74,6 +74,7 @@ * InvalidDigit * IBM Corporation - added the following constants * ParameterAssignment + * PossibleFallThroughCase *******************************************************************************/ package org.eclipse.jdt.core.compiler; @@ -406,6 +407,8 @@ // switch int IncorrectSwitchType = TypeRelated + 169; int DuplicateCase = FieldRelated + 170; + /** @since 3.2 */ + int PossibleFallThroughCase = Internal + 861; // labelled int DuplicateLabel = Internal + 171; int InvalidBreak = Internal + 172; 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.495 diff -u -r1.495 messages.properties --- batch/org/eclipse/jdt/internal/compiler/batch/messages.properties 10 Feb 2006 11:33:17 -0000 1.495 +++ batch/org/eclipse/jdt/internal/compiler/batch/messages.properties 13 Feb 2006 16:19:49 -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 13 Feb 2006 16:19:49 -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_ReportPossibleFallThroughCase, + 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 13 Feb 2006 16:19:55 -0000 @@ -562,3 +562,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 +861 = Possible fall-through case 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 13 Feb 2006 16:19:55 -0000 @@ -1535,6 +1535,9 @@ case IProblem.ParameterAssignment: return CompilerOptions.ParameterAssignment; + + case IProblem.PossibleFallThroughCase: + return CompilerOptions.PossibleFallThroughCase; } return 0; } @@ -4927,6 +4930,14 @@ start, end); } +public void possibleFallThroughCase(CaseStatement caseStatement) { + this.handle( + IProblem.PossibleFallThroughCase, + NoArgument, + NoArgument, + caseStatement.sourceStart, + caseStatement.sourceEnd); +} public void possibleAccidentalBooleanAssignment(Assignment assignment) { this.handle( IProblem.PossibleAccidentalBooleanAssignment, Index: compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java,v retrieving revision 1.339 diff -u -r1.339 Parser.java --- compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java 9 Feb 2006 16:01:30 -0000 1.339 +++ compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java 13 Feb 2006 16:19:53 -0000 @@ -1722,7 +1722,13 @@ // SwitchLabel ::= 'case' ConstantExpression ':' this.expressionLengthPtr--; Expression expression = this.expressionStack[this.expressionPtr--]; - pushOnAstStack(new CaseStatement(expression, expression.sourceEnd, this.intStack[this.intPtr--])); + CaseStatement caseStatement = + new CaseStatement(expression, expression.sourceEnd, this.intStack[this.intPtr--]); + if (this.scanner.protectedFallThroughCase) { + caseStatement.bits |= ASTNode.Bit19; + this.scanner.protectedFallThroughCase = false; + } + pushOnAstStack(caseStatement); } protected void consumeCastExpressionLL1() { //CastExpression ::= '(' Expression ')' InsideCastExpressionLL1 UnaryExpressionNotPlusMinus @@ -2528,7 +2534,13 @@ } protected void consumeDefaultLabel() { // SwitchLabel ::= 'default' ':' - pushOnAstStack(new CaseStatement(null, this.intStack[this.intPtr--], this.intStack[this.intPtr--])); + CaseStatement defaultStatement = + new CaseStatement(null, this.intStack[this.intPtr--], this.intStack[this.intPtr--]); + if (this.scanner.protectedFallThroughCase) { + defaultStatement.bits |= ASTNode.Bit19; + this.scanner.protectedFallThroughCase = false; + } + pushOnAstStack(defaultStatement); } protected void consumeDefaultModifiers() { checkComment(); // might update modifiers with AccDeprecated Index: compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java,v retrieving revision 1.169 diff -u -r1.169 Scanner.java --- compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java 9 Feb 2006 16:01:30 -0000 1.169 +++ compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java 13 Feb 2006 16:19:54 -0000 @@ -92,6 +92,14 @@ public int[] lineEnds = new int[250]; public int linePtr = -1; public boolean wasAcr = false; + + // support for line comments/case statement interaction + byte fallThroughCaseProtectionState = 0; + // -1: just passed a protection comment + // 0: starting a case/default with protection on OR just passed an end of line + // >0: passed multiple tokens since the last protection comment or end of line + public boolean protectedFallThroughCase = false; + // true iff the current case/default token is protected against fall-through public static final String END_OF_SOURCE = "End_Of_Source"; //$NON-NLS-1$ @@ -970,6 +978,11 @@ if (this.recordLineSeparator) { pushLineSeparator(); } + else { + this.fallThroughCaseProtectionState = 0; + // because the pass which records line separators is disjoint + // from the pass which reduces rules involving case/default + } } // inline version of: //isWhiteSpace = @@ -1007,6 +1020,7 @@ } } // ---------Identify the next token------------- + this.fallThroughCaseProtectionState++; // all non white space count switch (this.currentCharacter) { case '@' : /* if (this.sourceLevel >= ClassFileConstants.JDK1_5) { @@ -1331,7 +1345,13 @@ case '/' : { int test; - if ((test = getNextChar('/', '*')) == 0) { //line comment + if ((test = getNextChar('/', '*')) == 0) { //line comment + if (this.fallThroughCaseProtectionState == 1) { + this.fallThroughCaseProtectionState = -1; + } + else { + this.fallThroughCaseProtectionState = 0; + } this.lastCommentLinePosition = this.currentPosition; try { //get the next char if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\') @@ -1415,6 +1435,7 @@ break; } if (test > 0) { //traditional and javadoc comment + this.fallThroughCaseProtectionState = 0; try { //get the next char boolean isJavadoc = false, star = false; boolean isUnicode = false; @@ -2695,8 +2716,12 @@ switch (length) { case 4 : if (data[++index] == 'a') - if ((data[++index] == 's') && (data[++index] == 'e')) + if ((data[++index] == 's') && (data[++index] == 'e')) { + if (this.fallThroughCaseProtectionState == 0) { + this.protectedFallThroughCase = true; // parser resets it + } return TokenNamecase; + } else return TokenNameIdentifier; else @@ -2762,8 +2787,12 @@ && (data[++index] == 'a') && (data[++index] == 'u') && (data[++index] == 'l') - && (data[++index] == 't')) + && (data[++index] == 't')) { + if (this.fallThroughCaseProtectionState == 0) { + this.protectedFallThroughCase = true; // parser resets it + } return TokenNamedefault; + } else return TokenNameIdentifier; default : Index: model/org/eclipse/jdt/internal/core/util/PublicScanner.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/PublicScanner.java,v retrieving revision 1.86 diff -u -r1.86 PublicScanner.java --- model/org/eclipse/jdt/internal/core/util/PublicScanner.java 13 Feb 2006 09:32:57 -0000 1.86 +++ model/org/eclipse/jdt/internal/core/util/PublicScanner.java 13 Feb 2006 16:19:57 -0000 @@ -90,6 +90,14 @@ public int[] lineEnds = new int[250]; public int linePtr = -1; public boolean wasAcr = false; + + // support for line comments/case statement interaction + byte fallThroughCaseProtectionState = 0; + // -1: just passed a protection comment + // 0: starting a case/default with protection on OR just passed an end of line + // >0: passed multiple tokens since the last protection comment or end of line + public boolean protectedFallThroughCase = false; + // true iff the current case/default token is protected against fall-through public static final String END_OF_SOURCE = "End_Of_Source"; //$NON-NLS-1$ @@ -968,6 +976,11 @@ if (this.recordLineSeparator) { pushLineSeparator(); } + else { + this.fallThroughCaseProtectionState = 0; + // because the pass which records line separators is disjoint + // from the pass which reduces rules involving case/default + } } // inline version of: //isWhiteSpace = @@ -1005,6 +1018,7 @@ } } // ---------Identify the next token------------- + this.fallThroughCaseProtectionState++; // all non white space count switch (this.currentCharacter) { case '@' : /* if (this.sourceLevel >= ClassFileConstants.JDK1_5) { @@ -1329,7 +1343,13 @@ case '/' : { int test; - if ((test = getNextChar('/', '*')) == 0) { //line comment + if ((test = getNextChar('/', '*')) == 0) { //line comment + if (this.fallThroughCaseProtectionState == 1) { + this.fallThroughCaseProtectionState = -1; + } + else { + this.fallThroughCaseProtectionState = 0; + } this.lastCommentLinePosition = this.currentPosition; try { //get the next char if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\') @@ -1413,6 +1433,7 @@ break; } if (test > 0) { //traditional and javadoc comment + this.fallThroughCaseProtectionState = 0; try { //get the next char boolean isJavadoc = false, star = false; boolean isUnicode = false; @@ -2693,8 +2714,12 @@ switch (length) { case 4 : if (data[++index] == 'a') - if ((data[++index] == 's') && (data[++index] == 'e')) + if ((data[++index] == 's') && (data[++index] == 'e')) { + if (this.fallThroughCaseProtectionState == 0) { + this.protectedFallThroughCase = true; // parser resets it + } return TokenNamecase; + } else return TokenNameIdentifier; else @@ -2760,8 +2785,12 @@ && (data[++index] == 'a') && (data[++index] == 'u') && (data[++index] == 'l') - && (data[++index] == 't')) + && (data[++index] == 't')) { + if (this.fallThroughCaseProtectionState == 0) { + this.protectedFallThroughCase = true; // parser resets it + } return TokenNamedefault; + } else return TokenNameIdentifier; default : 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.531 diff -u -r1.531 JavaCore.java --- model/org/eclipse/jdt/core/JavaCore.java 9 Feb 2006 15:47:44 -0000 1.531 +++ model/org/eclipse/jdt/core/JavaCore.java 13 Feb 2006 16:19:56 -0000 @@ -2263,6 +2263,14 @@ * - possible values: { "error", "warning", "ignore" } * - default: "ignore" * + * + * COMPILER / Reporting Possible Fall-Through Case + * When enabled, the compiler will issue an error or a warning if a case may be + * reached in sequence from the preceeding, non empty case. + * - option id: "org.eclipse.jdt.core.compiler.problem.possibleFallThroughCase" + * - 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 13 Feb 2006 16:19:50 -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_ReportPossibleFallThroughCase = "org.eclipse.jdt.core.compiler.problem.possibleFallThroughCase"; //$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 PossibleFallThroughCase = 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_ReportPossibleFallThroughCase, getSeverityString(PossibleFallThroughCase)); 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_ReportPossibleFallThroughCase)) != null) updateSeverity(PossibleFallThroughCase, optionValue); // Javadoc options if ((optionValue = optionsMap.get(OPTION_DocCommentSupport)) != null) { @@ -891,6 +894,7 @@ OPTION_ReportOverridingPackageDefaultMethod, OPTION_ReportParameterAssignment, OPTION_ReportPossibleAccidentalBooleanAssignment, + OPTION_ReportPossibleFallThroughCase, OPTION_ReportSyntheticAccessEmulation, OPTION_ReportTypeParameterHiding, OPTION_ReportUncheckedTypeOperation, @@ -962,6 +966,8 @@ return "restriction"; //$NON-NLS-1$ case (int) (NullReference >>> 32) : return "null"; //$NON-NLS-1$ + case (int) (PossibleFallThroughCase >>> 32) : + return "fall-through"; //$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 ("fall-through".equals(warningToken)) //$NON-NLS-1$ + return PossibleFallThroughCase; if ("finally".equals(warningToken)) //$NON-NLS-1$ return FinallyBlockNotCompleting; break; #P org.eclipse.jdt.core.tests.compiler Index: src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java,v retrieving revision 1.2 diff -u -r1.2 FlowAnalysisTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java 10 Feb 2006 15:37:14 -0000 1.2 +++ src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java 13 Feb 2006 16:19:59 -0000 @@ -160,6 +160,388 @@ null, true, options); } +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=67836 +// [compiler] warning on fall through +// basic scenario +public void test006() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_ReportPossibleFallThroughCase, CompilerOptions.ERROR); + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " public void test(int p) {\n" + + " switch (p) {\n" + + " case 0:\n" + + " System.out.println(0); // silent because first case\n" + + " case 1:\n" + + " System.out.println(1); // complain: possible fall-through\n" + + " break;\n" + + " case 2:\n" + + " System.out.println(3); // silent because of break\n" + + " return;\n" + + " case 3: // silent because of return\n" + + " case 4: // silent because grouped cases\n" + + " default:\n" + + " System.out.println(\"default\"); //$NON-NLS-1$\n" + + " }\n" + + " }\n" + + "}" + }, + "----------\n" + + "1. ERROR in X.java (at line 6)\n" + + " case 1:\n" + + " ^^^^^^\n" + + "Possible fall-through case\n" + + "----------\n", + null, true, options); +} + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=67836 +// [compiler] warning on fall through +// SuppressWarnings effect - explicit fall-through token +public void test007() { + if (COMPLIANCE_1_5.equals(this.complianceLevel)) { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_ReportPossibleFallThroughCase, CompilerOptions.WARNING); + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " @SuppressWarnings(\"fall-through\")\n" + + " public void test(int p) {\n" + + " switch (p) {\n" + + " case 0:\n" + + " System.out.println(0); // silent because first case\n" + + " case 1:\n" + + " System.out.println(1); // silent because of SuppressWarnings\n" + + " }\n" + + " }\n" + + " Zork z;\n" + // complain on Zork (unknown type) + "}" + }, + "----------\n" + + "1. ERROR in X.java (at line 11)\n" + + " Zork z;\n" + + " ^^^^\n" + + "Zork cannot be resolved to a type\n" + + "----------\n", + null, true, options); + } +} + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=67836 +// [compiler] warning on fall through +// deep return (1) +public void test008() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_ReportPossibleFallThroughCase, CompilerOptions.ERROR); + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public void test(int p) {\n" + + " switch (p) {\n" + + " case 0:\n" + + " System.out.println(0);\n" + + " if (true) {\n" + + " return;\n" + + " }\n" + + " case 1:\n" + + " System.out.println(1);\n" + + " }\n" + + " }\n" + + "}" + }, + "", + null, true, null, options, null); +} + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=67836 +// [compiler] warning on fall through +// deep return (2) +public void test009() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_ReportPossibleFallThroughCase, CompilerOptions.ERROR); + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public void test(int p, boolean b) {\n" + + " switch (p) {\n" + + " case 0:\n" + + " System.out.println(0);\n" + + " if (b) {\n" + + " return;\n" + + " }\n" + + " else {\n" + + " return;\n" + + " }\n" + + " case 1:\n" + + " System.out.println(1);\n" + + " }\n" + + " }\n" + + "}" + }, + "", + null, true, null, options, null); +} + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=67836 +// [compiler] warning on fall through +// deep return (3), limit: cannot recognize that we won't return +public void test010() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_ReportPossibleFallThroughCase, CompilerOptions.ERROR); + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " public void test(int p, boolean b) {\n" + + " switch (p) {\n" + + " case 0:\n" + + " System.exit(0);\n" + + " case 1:\n" + // complain + " System.out.println(1);\n" + + " }\n" + + " }\n" + + "}" + }, + "----------\n" + + "1. ERROR in X.java (at line 6)\n" + + " case 1:\n" + + " ^^^^^^\n" + + "Possible fall-through case\n" + + "----------\n", + null, true, options); +} + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=67836 +// [compiler] warning on fall through +// SuppressWarnings effect - implicit, using all token +public void test011() { + if (COMPLIANCE_1_5.equals(this.complianceLevel)) { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_ReportPossibleFallThroughCase, CompilerOptions.WARNING); + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " @SuppressWarnings(\"all\")\n" + + " public void test(int p) {\n" + + " switch (p) {\n" + + " case 0:\n" + + " System.out.println(0); // silent because first case\n" + + " case 1:\n" + + " System.out.println(1); // silent because of SuppressWarnings\n" + + " }\n" + + " }\n" + + " Zork z;\n" + // complain on Zork (unknown type) + "}" + }, + "----------\n" + + "1. ERROR in X.java (at line 11)\n" + + " Zork z;\n" + + " ^^^^\n" + + "Zork cannot be resolved to a type\n" + + "----------\n", + null, true, options); + } +} + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=67836 +// [compiler] warning on fall through +// skip because of comment +public void test012() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_ReportPossibleFallThroughCase, CompilerOptions.ERROR); + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public void test(int p) {\n" + + " switch (p) {\n" + + " case 0:\n" + + " System.out.println(0); // silent because first case\n" + + " // on purpose fall-through\n" + + " case 1:\n" + + " System.out.println(1); // silent because of comment alone on its line above \n" + + " }\n" + + " }\n" + + "}" + }, + "", + null, true, null, options, null); +} + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=67836 +// [compiler] warning on fall through +// skip because of comment - default label +public void test013() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_ReportPossibleFallThroughCase, CompilerOptions.ERROR); + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public void test(int p) {\n" + + " switch (p) {\n" + + " case 0:\n" + + " System.out.println(0); // silent because first case\n" + + " // on purpose fall-through\n" + + " default:\n" + + " System.out.println(1); // silent because of comment alone on its line above \n" + + " }\n" + + " }\n" + + "}" + }, + "", + null, true, null, options, null); +} + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=67836 +// [compiler] warning on fall through +// basic scenario: default label +public void test014() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_ReportPossibleFallThroughCase, CompilerOptions.ERROR); + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " public void test(int p) {\n" + + " switch (p) {\n" + + " case 0:\n" + + " System.out.println(0); // silent because first case\n" + + // note: the comment above is not alone on its line, hence it does not + // protect against fall-through diagnostic + " default:\n" + + " System.out.println(1); // complain: possible fall-through\n" + + " }\n" + + " }\n" + + "}" + }, + "----------\n" + + "1. ERROR in X.java (at line 6)\n" + + " default:\n" + + " ^^^^^^^\n" + + "Possible fall-through case\n" + + "----------\n", + null, true, options); +} + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=67836 +// [compiler] warning on fall through +// skip because of comment - variants +public void test015() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_ReportPossibleFallThroughCase, CompilerOptions.ERROR); + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " public void test(int p) {\n" + + " switch (p) {\n" + + " case 0:\n" + + " System.out.println(0); // silent because first case\n" + + " // on purpose fall-through\n" + + "\n" + // extraneous line breaks fall-through protection + " case 1:\n" + + " System.out.println(1); // silent because of comment alone on its line above \n" + + " }\n" + + " }\n" + + "}" + }, + "----------\n" + + "1. ERROR in X.java (at line 8)\n" + + " case 1:\n" + + " ^^^^^^\n" + + "Possible fall-through case\n" + + "----------\n", + null, true, options); +} + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=67836 +// [compiler] warning on fall through +// skip because of comment - variants +public void test016() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_ReportPossibleFallThroughCase, CompilerOptions.ERROR); + this.runNegativeTest( + new String[] { + "X.java", + "public class X {\n" + + " public void test(int p) {\n" + + " switch (p) {\n" + + " case 0:\n" + + " System.out.println(0); // silent because first case\n" + + " // on purpose fall-through\n" + + " /* other comment */\n" + // non-single line comment breaks fall-through protection + " case 1:\n" + + " System.out.println(1); // silent because of comment alone on its line above \n" + + " }\n" + + " }\n" + + "}" + }, + "----------\n" + + "1. ERROR in X.java (at line 8)\n" + + " case 1:\n" + + " ^^^^^^\n" + + "Possible fall-through case\n" + + "----------\n", + null, true, options); +} + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=67836 +// [compiler] warning on fall through +// skip because of comment - variants +public void test017() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_ReportPossibleFallThroughCase, CompilerOptions.ERROR); + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public void test(int p) {\n" + + " switch (p) {\n" + + " case 0:\n" + + " System.out.println(0);\n" + + "// on purpose fall-through\n" + // very beginning of line + " case 1:\n" + + " System.out.println(1); // silent because of comment alone on its line above \n" + + " }\n" + + " }\n" + + "}" + }, + "", + null, true, null, options, null); +} + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=67836 +// [compiler] warning on fall through +// skip because of comment - variants +public void test018() { + Map options = getCompilerOptions(); + options.put(CompilerOptions.OPTION_ReportPossibleFallThroughCase, CompilerOptions.ERROR); + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public void test(int p) {\n" + + " switch (p) {\n" + + " case 0:\n" + + " System.out.println(0);\n" + + " //\n" + // empty line comment alone upon its line + " case 1:\n" + + " System.out.println(1); // silent because of comment alone on its line above \n" + + " }\n" + + " }\n" + + "}" + }, + "", + null, true, null, options, null); +} + public static Class testClass() { return FlowAnalysisTest.class; } Index: src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java,v retrieving revision 1.41 diff -u -r1.41 BatchCompilerTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java 2 Feb 2006 11:54:06 -0000 1.41 +++ src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java 13 Feb 2006 16:19:59 -0000 @@ -883,6 +883,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" + @@ -1063,6 +1064,7 @@ "