### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java,v retrieving revision 1.96 diff -u -r1.96 MethodVerifier.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java 27 Jun 2008 16:04:02 -0000 1.96 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java 1 Jul 2008 13:30:23 -0000 @@ -179,6 +179,8 @@ problemReporter(currentMethod).finalMethodCannotBeOverridden(currentMethod, inheritedMethod); if (!isAsVisible(currentMethod, inheritedMethod)) problemReporter(currentMethod).visibilityConflict(currentMethod, inheritedMethod); + if(inheritedMethod.isSynchronized() && !currentMethod.isSynchronized()) + problemReporter(currentMethod).missingSynchronizedOnInheritedMethod(currentMethod); if (options.reportDeprecationWhenOverridingDeprecatedMethod && inheritedMethod.isViewedAsDeprecated()) { if (!currentMethod.isViewedAsDeprecated() || options.reportDeprecationInsideDeprecatedCode) { // check against the other inherited methods to see if they hide this inheritedMethod 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.750 diff -u -r1.750 messages.properties --- batch/org/eclipse/jdt/internal/compiler/batch/messages.properties 1 Jul 2008 11:26:25 -0000 1.750 +++ batch/org/eclipse/jdt/internal/compiler/batch/messages.properties 1 Jul 2008 13:30:23 -0000 @@ -259,6 +259,7 @@ \ javadoc invalid javadoc\n\ \ localHiding local variable hiding another variable\n\ \ maskedCatchBlock + hidden catch block\n\ +\ missingSynchronizedOnInheritedMethod method missing synchronized of overridden method \ nls string literal lacking non-nls tag //$NON-NLS-$\n\ \ noEffectAssign + assignment without effect\n\ \ null potential missing or redundant null check\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.329 diff -u -r1.329 Main.java --- batch/org/eclipse/jdt/internal/compiler/batch/Main.java 27 Jun 2008 16:04:10 -0000 1.329 +++ batch/org/eclipse/jdt/internal/compiler/batch/Main.java 1 Jul 2008 13:30:23 -0000 @@ -3168,6 +3168,10 @@ this.options.put( CompilerOptions.OPTION_ReportComparingIdentical, isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); + } else if (token.equals("missingSynchronizedOnInheritedMethod")) { //$NON-NLS-1$ + this.options.put( + CompilerOptions.OPTION_ReportMissingSynchronizedOnInheritedMethod, + isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE); } else if (token.equals("intfNonInherited") || token.equals("interfaceNonInherited")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$ this.options.put( CompilerOptions.OPTION_ReportIncompatibleNonInheritedInterfaceMethod, 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.234 diff -u -r1.234 messages.properties --- compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties 23 Jun 2008 16:23:26 -0000 1.234 +++ compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties 1 Jul 2008 13:30:24 -0000 @@ -348,6 +348,7 @@ 414 = Exception {0} is not compatible with throws clause in {1}, thus this interface cannot be implemented 415 = The variable argument type {0} of the method {1} must be the last parameter 416 = The method {0} is overriding a method without making a super invocation +417 = The method {0}.{1} is overriding a method without being synchronized 420 = Code snippet support cannot find the class {0} 421 = Code snippet support cannot find the method {0}.{1}({2}) 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.372 diff -u -r1.372 ProblemReporter.java --- compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java 27 Jun 2008 16:04:14 -0000 1.372 +++ compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java 1 Jul 2008 13:30:24 -0000 @@ -318,6 +318,9 @@ case IProblem.ComparingIdentical: return CompilerOptions.ComparingIdentical; + + case IProblem.MissingSynchronizedModifierInInheritedMethod: + return CompilerOptions.MissingSynchronizedModifierInInheritedMethod; } return 0; } @@ -410,6 +413,7 @@ case (int)(CompilerOptions.FallthroughCase >>> 32): case (int)(CompilerOptions.OverridingMethodWithoutSuperInvocation >>> 32): case (int)(CompilerOptions.ComparingIdentical >>> 32): + case (int)(CompilerOptions.MissingSynchronizedModifierInInheritedMethod >> 32): return CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM; case (int)(CompilerOptions.TypeHiding >>> 32): @@ -4910,6 +4914,15 @@ typeDecl.sourceStart, typeDecl.sourceEnd); } +public void missingSynchronizedOnInheritedMethod(MethodBinding currentMethod) { + this.handle( + IProblem.MissingSynchronizedModifierInInheritedMethod, + new String[] {new String(currentMethod.declaringClass.readableName())}, + new String[] {new String(currentMethod.declaringClass.readableName()), + new String(currentMethod.readableName())}, + currentMethod.sourceStart(), + currentMethod.sourceEnd()); +} public void missingTypeInConstructor(ASTNode location, MethodBinding constructor) { List missingTypes = constructor.collectMissingTypes(null); TypeBinding missingType = (TypeBinding) missingTypes.get(0); 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.622 diff -u -r1.622 JavaCore.java --- model/org/eclipse/jdt/core/JavaCore.java 27 Jun 2008 16:04:01 -0000 1.622 +++ model/org/eclipse/jdt/core/JavaCore.java 1 Jul 2008 13:30:24 -0000 @@ -1468,7 +1468,19 @@ * @category CompilerOptionID */ public static final String COMPILER_PB_COMPARING_IDENTICAL = PLUGIN_ID + ".compiler.problem.comparingIdentical"; //$NON-NLS-1$ - + /** + * Compiler option ID: Reporting Missing Synchronized Modifier On Inherited Method. + *

When enabled, the compiler will issue an error or a warning if a method + * overrides a synchronized method without having a synchronized modifier. + *

+ *
Option id:
"org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod"
+ *
Possible values:
{ "error", "warning", "ignore" }
+ *
Default:
"warning"
+ *
+ * @since 3.5 + * @category CompilerOptionID + */ + public static final String COMPILER_PB_MISSING_SYNCHRONIZED_ON_INHERITED_METHOD = PLUGIN_ID + ".compiler.problem.missingSynchronizedOnInheritedMethod"; //$NON-NLS-1$ /** * Core option ID: Computing Project Build Order. *

Indicate whether JavaCore should enforce the project build order to be based on 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.205 diff -u -r1.205 CompilerOptions.java --- compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java 27 Jun 2008 16:04:13 -0000 1.205 +++ compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java 1 Jul 2008 13:30:23 -0000 @@ -120,6 +120,7 @@ public static final String OPTION_Process_Annotations = "org.eclipse.jdt.core.compiler.processAnnotations"; //$NON-NLS-1$ public static final String OPTION_ReportRedundantSuperinterface = "org.eclipse.jdt.core.compiler.problem.redundantSuperinterface"; //$NON-NLS-1$ public static final String OPTION_ReportComparingIdentical = "org.eclipse.jdt.core.compiler.problem.comparingIdentical"; //$NON-NLS-1$ + public static final String OPTION_ReportMissingSynchronizedOnInheritedMethod = "org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod"; //$NON-NLS-1$ // Backward compatibility public static final String OPTION_ReportInvalidAnnotation = "org.eclipse.jdt.core.compiler.problem.invalidAnnotation"; //$NON-NLS-1$ @@ -215,6 +216,7 @@ public static final long UnusedWarningToken = ASTNode.Bit55L; public static final long RedundantSuperinterface = ASTNode.Bit56L; public static final long ComparingIdentical = ASTNode.Bit57L; + public static final long MissingSynchronizedModifierInInheritedMethod= ASTNode.Bit58L; // Map: String optionKey --> Long irritant> private static Map OptionToIrritants; @@ -251,7 +253,8 @@ | UnusedTypeArguments | NullReference | UnusedWarningToken - | ComparingIdentical; + | ComparingIdentical + | MissingSynchronizedModifierInInheritedMethod; // By default only lines and source attributes are generated. public int produceDebugAttributes = ClassFileConstants.ATTR_SOURCE | ClassFileConstants.ATTR_LINES; @@ -463,6 +466,7 @@ optionsMap.put(OPTION_Process_Annotations, this.processAnnotations ? ENABLED : DISABLED); optionsMap.put(OPTION_ReportRedundantSuperinterface, getSeverityString(RedundantSuperinterface)); optionsMap.put(OPTION_ReportComparingIdentical, getSeverityString(ComparingIdentical)); + optionsMap.put(OPTION_ReportMissingSynchronizedOnInheritedMethod, getSeverityString(MissingSynchronizedModifierInInheritedMethod)); return optionsMap; } @@ -595,6 +599,8 @@ return OPTION_ReportRedundantSuperinterface; case (int)(ComparingIdentical >>> 32) : return OPTION_ReportComparingIdentical; + case (int)(MissingSynchronizedModifierInInheritedMethod >>> 32) : + return OPTION_ReportMissingSynchronizedOnInheritedMethod; } } return null; @@ -884,6 +890,7 @@ if ((optionValue = optionsMap.get(OPTION_ReportUnusedTypeArgumentsForMethodInvocation)) != null) updateSeverity(UnusedTypeArguments, optionValue); if ((optionValue = optionsMap.get(OPTION_ReportRedundantSuperinterface)) != null) updateSeverity(RedundantSuperinterface, optionValue); if ((optionValue = optionsMap.get(OPTION_ReportComparingIdentical)) != null) updateSeverity(ComparingIdentical, optionValue); + if ((optionValue = optionsMap.get(OPTION_ReportMissingSynchronizedOnInheritedMethod)) != null) updateSeverity(MissingSynchronizedModifierInInheritedMethod, optionValue); // Javadoc options if ((optionValue = optionsMap.get(OPTION_DocCommentSupport)) != null) { @@ -1081,6 +1088,7 @@ buf.append("\n\t- unused type arguments for method/constructor invocation: ").append(getSeverityString(UnusedTypeArguments)); //$NON-NLS-1$ buf.append("\n\t- redundant superinterface: ").append(getSeverityString(RedundantSuperinterface)); //$NON-NLS-1$ buf.append("\n\t- comparing identical expr: ").append(getSeverityString(ComparingIdentical)); //$NON-NLS-1$ + buf.append("\n\t- missing synchronized on inherited method: ").append(getSeverityString(MissingSynchronizedModifierInInheritedMethod)); //$NON-NLS-1$ return buf.toString(); } @@ -1321,6 +1329,7 @@ "unqualified-field-access", //$NON-NLS-1$ "unused", //$NON-NLS-1$ }; + public static long warningTokenToIrritants(String warningToken) { // keep in sync with warningTokens and warningTokenFromIrritant if (warningToken == null || warningToken.length() == 0) return 0; 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.201 diff -u -r1.201 IProblem.java --- compiler/org/eclipse/jdt/core/compiler/IProblem.java 27 Jun 2008 16:04:14 -0000 1.201 +++ compiler/org/eclipse/jdt/core/compiler/IProblem.java 1 Jul 2008 13:30:23 -0000 @@ -769,6 +769,8 @@ int IllegalVararg = MethodRelated + 415; /** @since 3.3 */ int OverridingMethodWithoutSuperInvocation = MethodRelated + 416; + /** @since 3.5 */ + int MissingSynchronizedModifierInInheritedMethod= MethodRelated + 417; // code snippet support int CodeSnippetMissingClass = Internal + 420; #P org.eclipse.jdt.doc.isv Index: guide/jdt_api_options.htm =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.doc.isv/guide/jdt_api_options.htm,v retrieving revision 1.67 diff -u -r1.67 jdt_api_options.htm --- guide/jdt_api_options.htm 3 Jun 2008 19:41:57 -0000 1.67 +++ guide/jdt_api_options.htm 1 Jul 2008 13:30:26 -0000 @@ -805,6 +805,20 @@ +Reporting Missing synchronized modifier of inherited methods (COMPILER_PB_MISSING_SYNCHRONIZED_ON_INHERITED_METHOD) + + +When enabled, the compiler will issue an error or a warning whenever a method overrides a synchronized method without having a synchronized modifier. +ERROR + + +WARNING + + +IGNORE + + + Reporting Assignment with No Effect (COMPILER_PB_NO_EFFECT_ASSIGNMENT) #P org.eclipse.jdt.core.tests.compiler Index: src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java,v retrieving revision 1.154 diff -u -r1.154 MethodVerifyTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java 27 Jun 2008 16:04:43 -0000 1.154 +++ src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java 1 Jul 2008 13:30:28 -0000 @@ -8676,4 +8676,21 @@ "----------\n" ); } + +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=239066 +public void test166() { + this.runNegativeTest( + new String[] { + "X.java", + "class X { synchronized void foo() {} }\n" + + "class Y extends X { @Override void foo() { } }" + }, + "----------\n" + + "1. WARNING in X.java (at line 2)\n" + + " class Y extends X { @Override void foo() { } }\n" + + " ^^^^^\n" + + "The method Y.foo() is overriding a method without being synchronized\n" + + "----------\n" + ); +} } \ No newline at end of file Index: src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java,v retrieving revision 1.17 diff -u -r1.17 CompilerInvocationTests.java --- src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java 27 Jun 2008 16:04:45 -0000 1.17 +++ src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java 1 Jul 2008 13:30:27 -0000 @@ -847,6 +847,7 @@ expectedProblemAttributes.put("JavadocTypeArgumentsForRawGenericConstructor", new ProblemAttributes(CategorizedProblem.CAT_JAVADOC)); expectedProblemAttributes.put("ExternalProblemNotFixable", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); expectedProblemAttributes.put("ExternalProblemFixable", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); + expectedProblemAttributes.put("MissingSynchronizedModifierInInheritedMethod", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); StringBuffer failures = new StringBuffer(); Field[] fields = (iProblemClass = IProblem.class).getFields(); boolean watchInternalCategory = false, printHeader = true; @@ -1994,6 +1995,7 @@ expectedProblemAttributes.put("ExternalProblemNotFixable", SKIP); expectedProblemAttributes.put("ExternalProblemFixable", SKIP); expectedProblemAttributes.put("ComparingIdentical", new ProblemAttributes(JavaCore.COMPILER_PB_COMPARING_IDENTICAL)); + expectedProblemAttributes.put("MissingSynchronizedModifierInInheritedMethod", new ProblemAttributes(JavaCore.COMPILER_PB_MISSING_SYNCHRONIZED_ON_INHERITED_METHOD)); Map constantNamesIndex = new HashMap(); Field[] fields = JavaCore.class.getFields(); for (int i = 0, length = fields.length; i < length; i++) {