Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 211642 Details for
Bug 359724
[organize imports] nested type imports not collapsed to wildcards ('*')
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read
this important communication.
[patch]
Path for this bug using egit
Fix-for-Bug-359724.patch (text/plain), 1.86 MB, created by
Samrat Dhillon
on 2012-02-26 13:54:48 EST
(
hide
)
Description:
Path for this bug using egit
Filename:
MIME Type:
Creator:
Samrat Dhillon
Created:
2012-02-26 13:54:48 EST
Size:
1.86 MB
patch
obsolete
>diff --git a/.gitignore b/.gitignore >index a4f9c0a..ecd8f25 100644 >--- a/.gitignore >+++ b/.gitignore >@@ -1,4 +1,4 @@ >-bin/ >+/*/bin/ > *~ > *.rej > *.bak >@@ -7,8 +7,7 @@ > heapdump.* > core.* > Snap.* >-target/ >-bin-resources/ >-binext/ >-binprocessors/ >-antbin/ >+/*/bin-resources/ >+/*/binext/ >+/*/binprocessors/ >+/*/antbin/ >diff --git a/org.eclipse.jdt.annotation/.classpath b/org.eclipse.jdt.annotation/.classpath >new file mode 100644 >index 0000000..304e861 >--- /dev/null >+++ b/org.eclipse.jdt.annotation/.classpath >@@ -0,0 +1,7 @@ >+<?xml version="1.0" encoding="UTF-8"?> >+<classpath> >+ <classpathentry kind="src" path="src"/> >+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/> >+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> >+ <classpathentry kind="output" path="bin"/> >+</classpath> >diff --git a/org.eclipse.jdt.annotation/.project b/org.eclipse.jdt.annotation/.project >new file mode 100644 >index 0000000..84d76bb >--- /dev/null >+++ b/org.eclipse.jdt.annotation/.project >@@ -0,0 +1,34 @@ >+<?xml version="1.0" encoding="UTF-8"?> >+<projectDescription> >+ <name>org.eclipse.jdt.annotation</name> >+ <comment></comment> >+ <projects> >+ </projects> >+ <buildSpec> >+ <buildCommand> >+ <name>org.eclipse.jdt.core.javabuilder</name> >+ <arguments> >+ </arguments> >+ </buildCommand> >+ <buildCommand> >+ <name>org.eclipse.pde.ManifestBuilder</name> >+ <arguments> >+ </arguments> >+ </buildCommand> >+ <buildCommand> >+ <name>org.eclipse.pde.SchemaBuilder</name> >+ <arguments> >+ </arguments> >+ </buildCommand> >+ <buildCommand> >+ <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name> >+ <arguments> >+ </arguments> >+ </buildCommand> >+ </buildSpec> >+ <natures> >+ <nature>org.eclipse.jdt.core.javanature</nature> >+ <nature>org.eclipse.pde.PluginNature</nature> >+ <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature> >+ </natures> >+</projectDescription> >diff --git a/org.eclipse.jdt.annotation/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.jdt.annotation/.settings/org.eclipse.core.runtime.prefs >new file mode 100644 >index 0000000..5a0ad22 >--- /dev/null >+++ b/org.eclipse.jdt.annotation/.settings/org.eclipse.core.runtime.prefs >@@ -0,0 +1,2 @@ >+eclipse.preferences.version=1 >+line.separator=\n >diff --git a/org.eclipse.jdt.annotation/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jdt.annotation/.settings/org.eclipse.jdt.core.prefs >new file mode 100644 >index 0000000..ccd5771 >--- /dev/null >+++ b/org.eclipse.jdt.annotation/.settings/org.eclipse.jdt.core.prefs >@@ -0,0 +1,364 @@ >+eclipse.preferences.version=1 >+org.eclipse.jdt.core.builder.cleanOutputFolder=clean >+org.eclipse.jdt.core.builder.duplicateResourceTask=warning >+org.eclipse.jdt.core.builder.invalidClasspath=abort >+org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore >+org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch,.svn/ >+org.eclipse.jdt.core.circularClasspath=error >+org.eclipse.jdt.core.classpath.exclusionPatterns=enabled >+org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled >+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled >+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 >+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve >+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.maxProblemPerUnit=100 >+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning >+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error >+org.eclipse.jdt.core.compiler.problem.autoboxing=warning >+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning >+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.explicitlyClosedAutoCloseable=warning >+org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning >+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled >+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning >+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.includeNullInfoFromAsserts=disabled >+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning >+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning >+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning >+org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning >+org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled >+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled >+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled >+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private >+org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning >+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning >+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore >+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning >+org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore >+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=enabled >+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public >+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore >+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=enabled >+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private >+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning >+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=warning >+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning >+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning >+org.eclipse.jdt.core.compiler.problem.nullReference=warning >+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning >+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore >+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning >+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore >+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=warning >+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning >+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning >+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning >+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning >+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore >+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=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=warning >+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning >+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled >+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning >+org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning >+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning >+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=warning >+org.eclipse.jdt.core.compiler.problem.unsafeTypeOperation=warning >+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=warning >+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore >+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 >+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false >+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 >+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 >+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 >+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 >+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 >+org.eclipse.jdt.core.formatter.alignment_for_assignment=0 >+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 >+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 >+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 >+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 >+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 >+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 >+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 >+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 >+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 >+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 >+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 >+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 >+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 >+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 >+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 >+org.eclipse.jdt.core.formatter.blank_lines_after_package=1 >+org.eclipse.jdt.core.formatter.blank_lines_before_field=0 >+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 >+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 >+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 >+org.eclipse.jdt.core.formatter.blank_lines_before_method=1 >+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 >+org.eclipse.jdt.core.formatter.blank_lines_before_package=0 >+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 >+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 >+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line >+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line >+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line >+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line >+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line >+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line >+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line >+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line >+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line >+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line >+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line >+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false >+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false >+org.eclipse.jdt.core.formatter.comment.format_block_comments=true >+org.eclipse.jdt.core.formatter.comment.format_header=false >+org.eclipse.jdt.core.formatter.comment.format_html=true >+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true >+org.eclipse.jdt.core.formatter.comment.format_line_comments=true >+org.eclipse.jdt.core.formatter.comment.format_source_code=true >+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true >+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true >+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert >+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert >+org.eclipse.jdt.core.formatter.comment.line_length=120 >+org.eclipse.jdt.core.formatter.compact_else_if=true >+org.eclipse.jdt.core.formatter.continuation_indentation=2 >+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 >+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false >+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true >+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true >+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true >+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true >+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true >+org.eclipse.jdt.core.formatter.indent_empty_lines=false >+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true >+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true >+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true >+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true >+org.eclipse.jdt.core.formatter.indentation.size=4 >+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert >+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert >+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert >+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert >+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert >+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert >+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert >+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert >+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert >+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert >+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert >+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert >+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert >+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert >+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert >+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert >+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert >+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert >+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert >+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert >+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert >+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert >+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert >+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert >+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert >+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert >+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert >+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert >+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert >+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert >+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert >+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert >+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert >+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert >+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert >+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert >+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert >+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert >+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert >+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert >+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert >+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert >+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert >+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert >+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert >+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert >+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert >+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert >+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert >+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert >+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert >+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert >+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false >+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false >+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false >+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false >+org.eclipse.jdt.core.formatter.lineSplit=120 >+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false >+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false >+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 >+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 >+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true >+org.eclipse.jdt.core.formatter.tabulation.char=tab >+org.eclipse.jdt.core.formatter.tabulation.size=4 >+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false >+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true >+org.eclipse.jdt.core.incompatibleJDKLevel=ignore >+org.eclipse.jdt.core.incompleteClasspath=error >diff --git a/org.eclipse.jdt.annotation/.settings/org.eclipse.jdt.launching.prefs b/org.eclipse.jdt.annotation/.settings/org.eclipse.jdt.launching.prefs >new file mode 100644 >index 0000000..2dcd706 >--- /dev/null >+++ b/org.eclipse.jdt.annotation/.settings/org.eclipse.jdt.launching.prefs >@@ -0,0 +1,3 @@ >+#Wed Feb 02 11:25:08 EST 2011 >+eclipse.preferences.version=1 >+org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=error >diff --git a/org.eclipse.jdt.annotation/.settings/org.eclipse.jdt.ui.prefs b/org.eclipse.jdt.annotation/.settings/org.eclipse.jdt.ui.prefs >new file mode 100644 >index 0000000..020f0ab >--- /dev/null >+++ b/org.eclipse.jdt.annotation/.settings/org.eclipse.jdt.ui.prefs >@@ -0,0 +1,105 @@ >+#Tue Jan 05 12:29:35 EST 2010 >+cleanup.add_default_serial_version_id=true >+cleanup.add_generated_serial_version_id=false >+cleanup.add_missing_annotations=true >+cleanup.add_missing_deprecated_annotations=true >+cleanup.add_missing_nls_tags=false >+cleanup.add_missing_override_annotations=true >+cleanup.add_serial_version_id=false >+cleanup.always_use_blocks=true >+cleanup.always_use_parentheses_in_expressions=false >+cleanup.always_use_this_for_non_static_field_access=true >+cleanup.always_use_this_for_non_static_method_access=false >+cleanup.convert_to_enhanced_for_loop=false >+cleanup.format_comment=false >+cleanup.format_javadoc=true >+cleanup.format_multi_line_comment=true >+cleanup.format_single_line_comment=true >+cleanup.format_source_code=false >+cleanup.make_local_variable_final=true >+cleanup.make_parameters_final=false >+cleanup.make_private_fields_final=true >+cleanup.make_variable_declarations_final=false >+cleanup.never_use_blocks=false >+cleanup.never_use_parentheses_in_expressions=true >+cleanup.organize_imports=true >+cleanup.qualify_static_field_accesses_with_declaring_class=true >+cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true >+cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true >+cleanup.qualify_static_member_accesses_with_declaring_class=true >+cleanup.qualify_static_method_accesses_with_declaring_class=false >+cleanup.remove_private_constructors=true >+cleanup.remove_unnecessary_casts=true >+cleanup.remove_unnecessary_nls_tags=true >+cleanup.remove_unused_imports=true >+cleanup.remove_unused_local_variables=false >+cleanup.remove_unused_private_fields=true >+cleanup.remove_unused_private_members=false >+cleanup.remove_unused_private_methods=true >+cleanup.remove_unused_private_types=true >+cleanup.use_blocks=false >+cleanup.use_blocks_only_for_return_and_throw=false >+cleanup.use_parentheses_in_expressions=false >+cleanup.use_this_for_non_static_field_access=true >+cleanup.use_this_for_non_static_field_access_only_if_necessary=false >+cleanup.use_this_for_non_static_method_access=false >+cleanup.use_this_for_non_static_method_access_only_if_necessary=true >+cleanup_profile=_Numbat >+cleanup_settings_version=2 >+eclipse.preferences.version=1 >+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true >+formatter_profile=_Jdtcore [built-in + Indent switch body + LineWidth\:120] >+formatter_settings_version=11 >+sp_cleanup.add_default_serial_version_id=true >+sp_cleanup.add_generated_serial_version_id=false >+sp_cleanup.add_missing_annotations=false >+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 >+sp_cleanup.always_use_this_for_non_static_field_access=false >+sp_cleanup.always_use_this_for_non_static_method_access=false >+sp_cleanup.convert_to_enhanced_for_loop=false >+sp_cleanup.correct_indentation=false >+sp_cleanup.format_source_code=false >+sp_cleanup.format_source_code_changes_only=false >+sp_cleanup.make_local_variable_final=false >+sp_cleanup.make_parameters_final=false >+sp_cleanup.make_private_fields_final=true >+sp_cleanup.make_type_abstract_if_missing_method=false >+sp_cleanup.make_variable_declarations_final=false >+sp_cleanup.never_use_blocks=false >+sp_cleanup.never_use_parentheses_in_expressions=true >+sp_cleanup.on_save_use_additional_actions=true >+sp_cleanup.organize_imports=false >+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false >+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true >+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true >+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false >+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false >+sp_cleanup.remove_private_constructors=true >+sp_cleanup.remove_trailing_whitespaces=false >+sp_cleanup.remove_trailing_whitespaces_all=true >+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false >+sp_cleanup.remove_unnecessary_casts=false >+sp_cleanup.remove_unnecessary_nls_tags=false >+sp_cleanup.remove_unused_imports=false >+sp_cleanup.remove_unused_local_variables=false >+sp_cleanup.remove_unused_private_fields=true >+sp_cleanup.remove_unused_private_members=false >+sp_cleanup.remove_unused_private_methods=true >+sp_cleanup.remove_unused_private_types=true >+sp_cleanup.sort_members=false >+sp_cleanup.sort_members_all=false >+sp_cleanup.update_ibm_copyright_to_current_year=true >+sp_cleanup.use_blocks=false >+sp_cleanup.use_blocks_only_for_return_and_throw=false >+sp_cleanup.use_parentheses_in_expressions=false >+sp_cleanup.use_this_for_non_static_field_access=false >+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true >+sp_cleanup.use_this_for_non_static_method_access=false >+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true >diff --git a/org.eclipse.jdt.annotation/.settings/org.eclipse.pde.api.tools.prefs b/org.eclipse.jdt.annotation/.settings/org.eclipse.pde.api.tools.prefs >new file mode 100644 >index 0000000..6f7536a >--- /dev/null >+++ b/org.eclipse.jdt.annotation/.settings/org.eclipse.pde.api.tools.prefs >@@ -0,0 +1,94 @@ >+#Fri May 21 10:24:07 EDT 2010 >+ANNOTATION_ELEMENT_TYPE_ADDED_METHOD_WITHOUT_DEFAULT_VALUE=Error >+ANNOTATION_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error >+ANNOTATION_ELEMENT_TYPE_REMOVED_FIELD=Error >+ANNOTATION_ELEMENT_TYPE_REMOVED_METHOD=Error >+ANNOTATION_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error >+API_COMPONENT_ELEMENT_TYPE_REMOVED_API_TYPE=Error >+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_API_TYPE=Error >+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_TYPE=Error >+API_COMPONENT_ELEMENT_TYPE_REMOVED_TYPE=Error >+CLASS_ELEMENT_TYPE_ADDED_METHOD=Error >+CLASS_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error >+CLASS_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error >+CLASS_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error >+CLASS_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error >+CLASS_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error >+CLASS_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error >+CLASS_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error >+CLASS_ELEMENT_TYPE_REMOVED_CONSTRUCTOR=Error >+CLASS_ELEMENT_TYPE_REMOVED_FIELD=Error >+CLASS_ELEMENT_TYPE_REMOVED_METHOD=Error >+CLASS_ELEMENT_TYPE_REMOVED_SUPERCLASS=Error >+CLASS_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error >+CLASS_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error >+CONSTRUCTOR_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error >+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error >+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error >+CONSTRUCTOR_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error >+ENUM_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error >+ENUM_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error >+ENUM_ELEMENT_TYPE_REMOVED_ENUM_CONSTANT=Error >+ENUM_ELEMENT_TYPE_REMOVED_FIELD=Error >+ENUM_ELEMENT_TYPE_REMOVED_METHOD=Error >+ENUM_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error >+FIELD_ELEMENT_TYPE_ADDED_VALUE=Error >+FIELD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error >+FIELD_ELEMENT_TYPE_CHANGED_FINAL_TO_NON_FINAL_STATIC_CONSTANT=Error >+FIELD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error >+FIELD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error >+FIELD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error >+FIELD_ELEMENT_TYPE_CHANGED_TYPE=Error >+FIELD_ELEMENT_TYPE_CHANGED_VALUE=Error >+FIELD_ELEMENT_TYPE_REMOVED_TYPE_ARGUMENT=Error >+FIELD_ELEMENT_TYPE_REMOVED_VALUE=Error >+ILLEGAL_EXTEND=Warning >+ILLEGAL_IMPLEMENT=Warning >+ILLEGAL_INSTANTIATE=Warning >+ILLEGAL_OVERRIDE=Warning >+ILLEGAL_REFERENCE=Warning >+INTERFACE_ELEMENT_TYPE_ADDED_FIELD=Error >+INTERFACE_ELEMENT_TYPE_ADDED_METHOD=Error >+INTERFACE_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error >+INTERFACE_ELEMENT_TYPE_ADDED_SUPER_INTERFACE_WITH_METHODS=Error >+INTERFACE_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error >+INTERFACE_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error >+INTERFACE_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error >+INTERFACE_ELEMENT_TYPE_REMOVED_FIELD=Error >+INTERFACE_ELEMENT_TYPE_REMOVED_METHOD=Error >+INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error >+INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error >+INVALID_JAVADOC_TAG=Warning >+INVALID_REFERENCE_IN_SYSTEM_LIBRARIES=Warning >+LEAK_EXTEND=Warning >+LEAK_FIELD_DECL=Warning >+LEAK_IMPLEMENT=Warning >+LEAK_METHOD_PARAM=Warning >+LEAK_METHOD_RETURN_TYPE=Warning >+METHOD_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error >+METHOD_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error >+METHOD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error >+METHOD_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error >+METHOD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error >+METHOD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error >+METHOD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error >+METHOD_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error >+METHOD_ELEMENT_TYPE_REMOVED_ANNOTATION_DEFAULT_VALUE=Error >+METHOD_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error >+TYPE_PARAMETER_ELEMENT_TYPE_ADDED_CLASS_BOUND=Error >+TYPE_PARAMETER_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Error >+TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Error >+TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_INTERFACE_BOUND=Error >+TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_CLASS_BOUND=Error >+TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_INTERFACE_BOUND=Error >+UNUSED_PROBLEM_FILTERS=Warning >+automatically_removed_unused_problem_filters=false >+eclipse.preferences.version=1 >+incompatible_api_component_version=Error >+incompatible_api_component_version_include_major_without_breaking_change=Disabled >+incompatible_api_component_version_include_minor_without_api_change=Disabled >+invalid_since_tag_version=Error >+malformed_since_tag=Error >+missing_since_tag=Error >+report_api_breakage_when_major_version_incremented=Disabled >+report_resolution_errors_api_component=Warning >diff --git a/org.eclipse.jdt.annotation/.settings/org.eclipse.pde.prefs b/org.eclipse.jdt.annotation/.settings/org.eclipse.pde.prefs >new file mode 100644 >index 0000000..35bb407 >--- /dev/null >+++ b/org.eclipse.jdt.annotation/.settings/org.eclipse.pde.prefs >@@ -0,0 +1,35 @@ >+#Fri May 21 10:24:08 EDT 2010 >+compilers.f.unresolved-features=1 >+compilers.f.unresolved-plugins=1 >+compilers.incompatible-environment=1 >+compilers.p.build=1 >+compilers.p.build.bin.includes=1 >+compilers.p.build.encodings=2 >+compilers.p.build.java.compiler=2 >+compilers.p.build.java.compliance=2 >+compilers.p.build.missing.output=2 >+compilers.p.build.output.library=2 >+compilers.p.build.source.library=2 >+compilers.p.build.src.includes=1 >+compilers.p.deprecated=1 >+compilers.p.discouraged-class=1 >+compilers.p.internal=1 >+compilers.p.missing-bundle-classpath-entries=2 >+compilers.p.missing-packages=2 >+compilers.p.missing-version-export-package=2 >+compilers.p.missing-version-import-package=2 >+compilers.p.missing-version-require-bundle=2 >+compilers.p.no-required-att=0 >+compilers.p.not-externalized-att=2 >+compilers.p.unknown-attribute=1 >+compilers.p.unknown-class=1 >+compilers.p.unknown-element=1 >+compilers.p.unknown-identifier=1 >+compilers.p.unknown-resource=1 >+compilers.p.unresolved-ex-points=0 >+compilers.p.unresolved-import=0 >+compilers.s.create-docs=false >+compilers.s.doc-folder=doc >+compilers.s.open-tags=1 >+compilers.use-project=true >+eclipse.preferences.version=1 >diff --git a/org.eclipse.jdt.annotation/META-INF/MANIFEST.MF b/org.eclipse.jdt.annotation/META-INF/MANIFEST.MF >new file mode 100644 >index 0000000..227f618 >--- /dev/null >+++ b/org.eclipse.jdt.annotation/META-INF/MANIFEST.MF >@@ -0,0 +1,9 @@ >+Manifest-Version: 1.0 >+Bundle-ManifestVersion: 2 >+Bundle-Name: %bundleName >+Bundle-Localization: bundle >+Bundle-SymbolicName: org.eclipse.jdt.annotation >+Bundle-Version: 1.0.0.qualifier >+Export-Package: org.eclipse.jdt.annotation >+Bundle-RequiredExecutionEnvironment: J2SE-1.5 >+Bundle-Vendor: %providerName >diff --git a/org.eclipse.jdt.annotation/about.html b/org.eclipse.jdt.annotation/about.html >new file mode 100644 >index 0000000..c258ef5 >--- /dev/null >+++ b/org.eclipse.jdt.annotation/about.html >@@ -0,0 +1,28 @@ >+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" >+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> >+<html xmlns="http://www.w3.org/1999/xhtml"> >+<head> >+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/> >+<title>About</title> >+</head> >+<body lang="EN-US"> >+<h2>About This Content</h2> >+ >+<p>June 5, 2006</p> >+<h3>License</h3> >+ >+<p>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 <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>. >+For purposes of the EPL, "Program" will mean the Content.</p> >+ >+<p>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 <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p> >+ >+</body> >+</html> >\ No newline at end of file >diff --git a/org.eclipse.jdt.annotation/build.properties b/org.eclipse.jdt.annotation/build.properties >new file mode 100644 >index 0000000..153d0b7 >--- /dev/null >+++ b/org.eclipse.jdt.annotation/build.properties >@@ -0,0 +1,18 @@ >+############################################################################### >+# Copyright (c) 2011 Stephan Herrmann 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: >+# Stephan Herrmann - initial API and implementation >+# IBM Corporation - bug fixes >+############################################################################### >+source.. = src/ >+bin.includes = META-INF/,\ >+ .,\ >+ bundle.properties,\ >+ src/,\ >+ about.html >+src.includes = about.html >diff --git a/org.eclipse.jdt.annotation/bundle.properties b/org.eclipse.jdt.annotation/bundle.properties >new file mode 100644 >index 0000000..e4bef55 >--- /dev/null >+++ b/org.eclipse.jdt.annotation/bundle.properties >@@ -0,0 +1,12 @@ >+############################################################################### >+# Copyright (c) 2011 Stephan Herrmann. >+# 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: >+# Stephan Herrmann - initial API and implementation >+############################################################################### >+providerName=Eclipse.org >+bundleName=JDT Annotations for Enhanced Null Analysis >diff --git a/org.eclipse.jdt.annotation/src/org/eclipse/jdt/annotation/NonNull.java b/org.eclipse.jdt.annotation/src/org/eclipse/jdt/annotation/NonNull.java >new file mode 100644 >index 0000000..9372739 >--- /dev/null >+++ b/org.eclipse.jdt.annotation/src/org/eclipse/jdt/annotation/NonNull.java >@@ -0,0 +1,50 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 Stephan Herrmann 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: >+ * Stephan Herrmann - initial API and implementation >+ * IBM Corporation - bug fixes >+ *******************************************************************************/ >+package org.eclipse.jdt.annotation; >+ >+import static java.lang.annotation.ElementType.LOCAL_VARIABLE; >+import static java.lang.annotation.ElementType.METHOD; >+import static java.lang.annotation.ElementType.PARAMETER; >+ >+import java.lang.annotation.Documented; >+import java.lang.annotation.Retention; >+import java.lang.annotation.RetentionPolicy; >+import java.lang.annotation.Target; >+ >+/** >+ * Qualifier for a type in a method signature or a local variable declaration: >+ * The entity (return value, parameter, local variable) whose type has this >+ * annotation can never have the value <code>null</code> at runtime. >+ * <p> >+ * This has two consequences: >+ * <ol> >+ * <li>Dereferencing the entity is safe, i.e., no <code>NullPointerException</code> can occur at runtime.</li> >+ * <li>An attempt to bind a <code>null</code> value to the entity is a compile time error.</li> >+ * </ol> >+ * For the second case, diagnostics issued by the compiler should distinguish three situations: >+ * <ol> >+ * <li>Nullness of the value can be statically determined, the entity is definitely bound from either of: >+ * <ul><li>the value <code>null</code>, or</li> >+ * <li>an entity with a {@link Nullable @Nullable} type.</li></ul></li> >+ * <li>Nullness cannot definitely be determined, because different code branches yield different results.</li> >+ * <li>Nullness cannot be determined, because other program elements are involved for which >+ * null annotations are lacking.</li> >+ * </ol> >+ * </p> >+ * @since 1.0 >+ */ >+@Documented >+@Retention(RetentionPolicy.CLASS) >+@Target({ METHOD, PARAMETER, LOCAL_VARIABLE }) >+public @interface NonNull { >+ // marker annotation with no members >+} >diff --git a/org.eclipse.jdt.annotation/src/org/eclipse/jdt/annotation/NonNullByDefault.java b/org.eclipse.jdt.annotation/src/org/eclipse/jdt/annotation/NonNullByDefault.java >new file mode 100644 >index 0000000..0ef1cac >--- /dev/null >+++ b/org.eclipse.jdt.annotation/src/org/eclipse/jdt/annotation/NonNullByDefault.java >@@ -0,0 +1,52 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 Stephan Herrmann 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: >+ * Stephan Herrmann - initial API and implementation >+ * IBM Corporation - bug fixes >+ *******************************************************************************/ >+package org.eclipse.jdt.annotation; >+ >+import static java.lang.annotation.ElementType.CONSTRUCTOR; >+import static java.lang.annotation.ElementType.METHOD; >+import static java.lang.annotation.ElementType.PACKAGE; >+import static java.lang.annotation.ElementType.TYPE; >+ >+import java.lang.annotation.Documented; >+import java.lang.annotation.Retention; >+import java.lang.annotation.RetentionPolicy; >+import java.lang.annotation.Target; >+ >+/** >+ * This annotation can be applied to a package, type, method or constructor in order to >+ * define that all contained entities for which a null annotation is otherwise lacking >+ * should be considered as {@link NonNull @NonNull}. >+ * <dl> >+ * <dt>Canceling a default</dt> >+ * <dd>By using a <code>@NonNullByDefault</code> annotation with the argument <code>false</code>, >+ * a default from any enclosing scope can be canceled for the element being annotated. >+ * <dt>Nested defaults</dt> >+ * <dd>If a <code>@NonNullByDefault</code> >+ * annotation is used within the scope of another <code>@NonNullByDefault</code> >+ * annotation or a project-wide default setting, the innermost annotation defines the >+ * default applicable at any given position (depending on the parameter {@link #value()}).</dd> >+ * </dl> >+ * Note that for applying an annotation to a package, a file by the name >+ * <code>package-info.java</code> is used. >+ * >+ * @since 1.0 >+ */ >+@Documented >+@Retention(RetentionPolicy.CLASS) >+@Target({ PACKAGE, TYPE, METHOD, CONSTRUCTOR }) >+public @interface NonNullByDefault { >+ /** >+ * When parameterized with <code>false</code>, the annotation specifies that the current element should not apply >+ * any default to un-annotated types. >+ */ >+ boolean value() default true; >+} >diff --git a/org.eclipse.jdt.annotation/src/org/eclipse/jdt/annotation/Nullable.java b/org.eclipse.jdt.annotation/src/org/eclipse/jdt/annotation/Nullable.java >new file mode 100644 >index 0000000..41f93cd >--- /dev/null >+++ b/org.eclipse.jdt.annotation/src/org/eclipse/jdt/annotation/Nullable.java >@@ -0,0 +1,41 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 Stephan Herrmann 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: >+ * Stephan Herrmann - initial API and implementation >+ * IBM Corporation - bug fixes >+ *******************************************************************************/ >+package org.eclipse.jdt.annotation; >+ >+import static java.lang.annotation.ElementType.LOCAL_VARIABLE; >+import static java.lang.annotation.ElementType.METHOD; >+import static java.lang.annotation.ElementType.PARAMETER; >+ >+import java.lang.annotation.Documented; >+import java.lang.annotation.Retention; >+import java.lang.annotation.RetentionPolicy; >+import java.lang.annotation.Target; >+ >+/** >+ * Qualifier for a type in a method signature or a local variable declaration: >+ * The entity (return value, parameter, local variable) whose type has this >+ * annotation is allowed to have the value <code>null</code> at runtime. >+ * <p> >+ * This has two consequences: >+ * <ul> >+ * <li>Binding a <code>null</code> value to the entity is legal.</li> >+ * <li>Dereferencing the entity is unsafe, i.e., a <code>NullPointerException</code> can occur at runtime.</li> >+ * </ul> >+ * </p> >+ * @since 1.0 >+ */ >+@Documented >+@Retention(RetentionPolicy.CLASS) >+@Target({ METHOD, PARAMETER, LOCAL_VARIABLE }) >+public @interface Nullable { >+ // marker annotation with no members >+} >\ No newline at end of file >diff --git a/org.eclipse.jdt.annotation/src/org/eclipse/jdt/annotation/package-info.java b/org.eclipse.jdt.annotation/src/org/eclipse/jdt/annotation/package-info.java >new file mode 100644 >index 0000000..62f91ff >--- /dev/null >+++ b/org.eclipse.jdt.annotation/src/org/eclipse/jdt/annotation/package-info.java >@@ -0,0 +1,10 @@ >+/** >+ * This package contains annotations that can trigger special behavior >+ * when annotated types are compiled by the Eclipse Compiler for Java. >+ * <p> >+ * Currently, the package contains annotations that specify nullness contracts >+ * for annotated elements. >+ * </p> >+ */ >+package org.eclipse.jdt.annotation; >+ >diff --git a/org.eclipse.jdt.apt.core/.cvsignore b/org.eclipse.jdt.apt.core/.cvsignore >deleted file mode 100755 >index 1fe7c80..0000000 >--- a/org.eclipse.jdt.apt.core/.cvsignore >+++ /dev/null >@@ -1,2 +0,0 @@ >-bin >-tools.jar >\ No newline at end of file >diff --git a/org.eclipse.jdt.apt.core/.settings/org.eclipse.core.resources.prefs b/org.eclipse.jdt.apt.core/.settings/org.eclipse.core.resources.prefs >index 86c2fda..bf068cf 100644 >--- a/org.eclipse.jdt.apt.core/.settings/org.eclipse.core.resources.prefs >+++ b/org.eclipse.jdt.apt.core/.settings/org.eclipse.core.resources.prefs >@@ -1,5 +1,5 @@ >-#Mon Mar 20 17:21:22 PST 2006 >-eclipse.preferences.version=1 >-encoding//src/org/eclipse/jdt/apt/core/internal/build/messages.properties=8859_1 >-encoding//src/org/eclipse/jdt/apt/core/internal/messages.properties=8859_1 >-encoding//src/org/eclipse/jdt/apt/core/internal/util/messages.properties=8859_1 >+#Mon Mar 20 17:21:22 PST 2006 >+eclipse.preferences.version=1 >+encoding//src/org/eclipse/jdt/apt/core/internal/build/messages.properties=8859_1 >+encoding//src/org/eclipse/jdt/apt/core/internal/messages.properties=8859_1 >+encoding//src/org/eclipse/jdt/apt/core/internal/util/messages.properties=8859_1 >diff --git a/org.eclipse.jdt.apt.core/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.jdt.apt.core/.settings/org.eclipse.core.runtime.prefs >new file mode 100644 >index 0000000..5a0ad22 >--- /dev/null >+++ b/org.eclipse.jdt.apt.core/.settings/org.eclipse.core.runtime.prefs >@@ -0,0 +1,2 @@ >+eclipse.preferences.version=1 >+line.separator=\n >diff --git a/org.eclipse.jdt.apt.pluggable.core/.cvsignore b/org.eclipse.jdt.apt.pluggable.core/.cvsignore >deleted file mode 100644 >index c5e82d7..0000000 >--- a/org.eclipse.jdt.apt.pluggable.core/.cvsignore >+++ /dev/null >@@ -1 +0,0 @@ >-bin >\ No newline at end of file >diff --git a/org.eclipse.jdt.apt.pluggable.core/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.jdt.apt.pluggable.core/.settings/org.eclipse.core.runtime.prefs >new file mode 100644 >index 0000000..5a0ad22 >--- /dev/null >+++ b/org.eclipse.jdt.apt.pluggable.core/.settings/org.eclipse.core.runtime.prefs >@@ -0,0 +1,2 @@ >+eclipse.preferences.version=1 >+line.separator=\n >diff --git a/org.eclipse.jdt.apt.pluggable.tests/.cvsignore b/org.eclipse.jdt.apt.pluggable.tests/.cvsignore >deleted file mode 100644 >index c5e82d7..0000000 >--- a/org.eclipse.jdt.apt.pluggable.tests/.cvsignore >+++ /dev/null >@@ -1 +0,0 @@ >-bin >\ No newline at end of file >diff --git a/org.eclipse.jdt.apt.pluggable.tests/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.jdt.apt.pluggable.tests/.settings/org.eclipse.core.runtime.prefs >new file mode 100644 >index 0000000..5a0ad22 >--- /dev/null >+++ b/org.eclipse.jdt.apt.pluggable.tests/.settings/org.eclipse.core.runtime.prefs >@@ -0,0 +1,2 @@ >+eclipse.preferences.version=1 >+line.separator=\n >diff --git a/org.eclipse.jdt.apt.pluggable.tests/src/org/eclipse/jdt/apt/pluggable/tests/processors/modeltester/ModelTesterProc.java b/org.eclipse.jdt.apt.pluggable.tests/src/org/eclipse/jdt/apt/pluggable/tests/processors/modeltester/ModelTesterProc.java >index b34dd26..828f914 100644 >--- a/org.eclipse.jdt.apt.pluggable.tests/src/org/eclipse/jdt/apt/pluggable/tests/processors/modeltester/ModelTesterProc.java >+++ b/org.eclipse.jdt.apt.pluggable.tests/src/org/eclipse/jdt/apt/pluggable/tests/processors/modeltester/ModelTesterProc.java >@@ -54,12 +54,11 @@ > > public static final String TEST_FIELD_TYPE_PKG = "p"; > public static final String TEST_FIELD_TYPE_CLASS = "Foo"; >- public static final String TEST_FIELD_TYPE_SOURCE = >+ public static final String TEST_FIELD_TYPE_SOURCE = > "package p;\n" + > "import org.eclipse.jdt.apt.pluggable.tests.annotations.ModelTestTrigger;\n" + > "import org.eclipse.jdt.apt.pluggable.tests.annotations.LookAt;\n" + > "@ModelTestTrigger(test = \"testFieldType\")" + >- "@SuppressWarnings(\"unused\")\n" + > "public class Foo {\n" + > " @LookAt\n" + > " private int _fInt = 0;\n" + >@@ -71,12 +70,11 @@ > > public static final String TEST_METHOD_TYPE_PKG = "p"; > public static final String TEST_METHOD_TYPE_CLASS = "Foo"; >- public static final String TEST_METHOD_TYPE_SOURCE = >+ public static final String TEST_METHOD_TYPE_SOURCE = > "package p;\n" + > "import org.eclipse.jdt.apt.pluggable.tests.annotations.ModelTestTrigger;\n" + > "import org.eclipse.jdt.apt.pluggable.tests.annotations.LookAt;\n" + > "@ModelTestTrigger(test = \"testMethodType\")" + >- "@SuppressWarnings(\"unused\")\n" + > "public class Foo {\n" + > " @LookAt\n" + > " private Foo self() { return this;}\n" + >diff --git a/org.eclipse.jdt.apt.pluggable.tests/test.xml b/org.eclipse.jdt.apt.pluggable.tests/test.xml >index 8150935..c958856 100644 >--- a/org.eclipse.jdt.apt.pluggable.tests/test.xml >+++ b/org.eclipse.jdt.apt.pluggable.tests/test.xml >@@ -1,7 +1,7 @@ >-<?xml version="1.0"?> >+<?xml version="1.0" encoding="UTF-8"?> > > <!-- >- Copyright (c) 2005, 2010 IBM Corporation and others. >+ Copyright (c) 2005, 2011 IBM Corporation 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 >diff --git a/org.eclipse.jdt.apt.tests/.cvsignore b/org.eclipse.jdt.apt.tests/.cvsignore >deleted file mode 100755 >index d30794a..0000000 >--- a/org.eclipse.jdt.apt.tests/.cvsignore >+++ /dev/null >@@ -1,2 +0,0 @@ >-bin >-binext >diff --git a/org.eclipse.jdt.apt.tests/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.jdt.apt.tests/.settings/org.eclipse.core.runtime.prefs >new file mode 100644 >index 0000000..5a0ad22 >--- /dev/null >+++ b/org.eclipse.jdt.apt.tests/.settings/org.eclipse.core.runtime.prefs >@@ -0,0 +1,2 @@ >+eclipse.preferences.version=1 >+line.separator=\n >diff --git a/org.eclipse.jdt.apt.tests/META-INF/MANIFEST.MF b/org.eclipse.jdt.apt.tests/META-INF/MANIFEST.MF >index b90295d..c940708 100644 >--- a/org.eclipse.jdt.apt.tests/META-INF/MANIFEST.MF >+++ b/org.eclipse.jdt.apt.tests/META-INF/MANIFEST.MF >@@ -36,7 +36,8 @@ > org.eclipse.jdt.core.tests.model, > org.eclipse.core.resources, > org.eclipse.core.runtime, >- org.eclipse.test.performance >+ org.eclipse.test.performance, >+ org.eclipse.jdt.core.tests.binaries;bundle-version="1.0.0" > Bundle-ActivationPolicy: lazy > Bundle-RequiredExecutionEnvironment: J2SE-1.5 > Bundle-Vendor: %providerName >diff --git a/org.eclipse.jdt.apt.tests/build.properties b/org.eclipse.jdt.apt.tests/build.properties >index b8d99e4..b49f00a 100644 >--- a/org.eclipse.jdt.apt.tests/build.properties >+++ b/org.eclipse.jdt.apt.tests/build.properties >@@ -1,5 +1,5 @@ > ############################################################################### >-# Copyright (c) 2005, 2007 BEA Systems, Inc. >+# Copyright (c) 2005, 2011 BEA Systems, Inc. > # 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,7 +10,6 @@ > output.apt.jar = bin/ > bin.includes = plugin.xml,\ > test.xml,\ >- perf-test-project.zip,\ > META-INF/,\ > resources/,\ > *.jar,\ >diff --git a/org.eclipse.jdt.apt.tests/src/org/eclipse/jdt/apt/tests/PerfTests.java b/org.eclipse.jdt.apt.tests/src/org/eclipse/jdt/apt/tests/PerfTests.java >index 63b97b8..b61f8ad 100644 >--- a/org.eclipse.jdt.apt.tests/src/org/eclipse/jdt/apt/tests/PerfTests.java >+++ b/org.eclipse.jdt.apt.tests/src/org/eclipse/jdt/apt/tests/PerfTests.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2005, 2007 BEA Systems, Inc. >+ * Copyright (c) 2005, 2011 BEA Systems, Inc. > * 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 >@@ -59,12 +59,10 @@ > IPath path = root.getLocation(); > File destRoot = path.toFile(); > >- URL platformURL = Platform.getBundle("org.eclipse.jdt.apt.tests").getEntry("/"); //$NON-NLS-1$//$NON-NLS-2$ >+ URL platformURL = Platform.getBundle("org.eclipse.jdt.core.tests.binaries").getEntry("/"); //$NON-NLS-1$//$NON-NLS-2$ > File f = new File(FileLocator.toFileURL(platformURL).getFile()); > f = new File(f, "perf-test-project.zip"); //$NON-NLS-1$ > >- >- //InputStream in = PerfTests.class.getClassLoader().getResourceAsStream("perf-test-project.zip"); > InputStream in = new FileInputStream(f); > ZipInputStream zipIn = new ZipInputStream(in); > try { >diff --git a/org.eclipse.jdt.apt.tests/test.xml b/org.eclipse.jdt.apt.tests/test.xml >index 7a6fa9d..485d9fb 100644 >--- a/org.eclipse.jdt.apt.tests/test.xml >+++ b/org.eclipse.jdt.apt.tests/test.xml >@@ -1,7 +1,7 @@ >-<?xml version="1.0"?> >+<?xml version="1.0" encoding="UTF-8"?> > > <!-- >- Copyright (c) 2005, 2010 IBM Corporation and others. >+ Copyright (c) 2005, 2011 IBM Corporation 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 >diff --git a/org.eclipse.jdt.apt.ui/.cvsignore b/org.eclipse.jdt.apt.ui/.cvsignore >deleted file mode 100644 >index ba077a4..0000000 >--- a/org.eclipse.jdt.apt.ui/.cvsignore >+++ /dev/null >@@ -1 +0,0 @@ >-bin >diff --git a/org.eclipse.jdt.apt.ui/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.jdt.apt.ui/.settings/org.eclipse.core.runtime.prefs >new file mode 100644 >index 0000000..5a0ad22 >--- /dev/null >+++ b/org.eclipse.jdt.apt.ui/.settings/org.eclipse.core.runtime.prefs >@@ -0,0 +1,2 @@ >+eclipse.preferences.version=1 >+line.separator=\n >diff --git a/org.eclipse.jdt.compiler.apt.tests/.cvsignore b/org.eclipse.jdt.compiler.apt.tests/.cvsignore >deleted file mode 100644 >index 5a17507..0000000 >--- a/org.eclipse.jdt.compiler.apt.tests/.cvsignore >+++ /dev/null >@@ -1,3 +0,0 @@ >-bin >-binprocessors >-lib >\ No newline at end of file >diff --git a/org.eclipse.jdt.compiler.apt.tests/.gitignore b/org.eclipse.jdt.compiler.apt.tests/.gitignore >new file mode 100644 >index 0000000..502167f >--- /dev/null >+++ b/org.eclipse.jdt.compiler.apt.tests/.gitignore >@@ -0,0 +1 @@ >+/lib >diff --git a/org.eclipse.jdt.compiler.apt.tests/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.jdt.compiler.apt.tests/.settings/org.eclipse.core.runtime.prefs >new file mode 100644 >index 0000000..c522e1f >--- /dev/null >+++ b/org.eclipse.jdt.compiler.apt.tests/.settings/org.eclipse.core.runtime.prefs >@@ -0,0 +1,2 @@ >+eclipse.preferences.version=1 >+line.separator=\n >diff --git a/org.eclipse.jdt.compiler.apt.tests/test.xml b/org.eclipse.jdt.compiler.apt.tests/test.xml >index b25d390..c189f23 100644 >--- a/org.eclipse.jdt.compiler.apt.tests/test.xml >+++ b/org.eclipse.jdt.compiler.apt.tests/test.xml >@@ -1,7 +1,7 @@ >-<?xml version="1.0"?> >+<?xml version="1.0" encoding="UTF-8"?> > > <!-- >- Copyright (c) 2005, 2010 IBM Corporation and others. >+ Copyright (c) 2005, 2011 IBM Corporation 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 >diff --git a/org.eclipse.jdt.compiler.apt/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.jdt.compiler.apt/.settings/org.eclipse.core.runtime.prefs >new file mode 100644 >index 0000000..5a0ad22 >--- /dev/null >+++ b/org.eclipse.jdt.compiler.apt/.settings/org.eclipse.core.runtime.prefs >@@ -0,0 +1,2 @@ >+eclipse.preferences.version=1 >+line.separator=\n >diff --git a/org.eclipse.jdt.compiler.apt/META-INF/MANIFEST.MF b/org.eclipse.jdt.compiler.apt/META-INF/MANIFEST.MF >index 8fdde2f..d4d1756 100644 >--- a/org.eclipse.jdt.compiler.apt/META-INF/MANIFEST.MF >+++ b/org.eclipse.jdt.compiler.apt/META-INF/MANIFEST.MF >@@ -2,7 +2,7 @@ > Bundle-ManifestVersion: 2 > Bundle-Name: %fragmentName > Bundle-SymbolicName: org.eclipse.jdt.compiler.apt;singleton:=true >-Bundle-Version: 1.0.400.qualifier >+Bundle-Version: 1.0.500.qualifier > Bundle-RequiredExecutionEnvironment: JavaSE-1.6 > Bundle-Vendor: %providerName > Fragment-Host: org.eclipse.jdt.core;bundle-version="[3.5.0,4.0.0)" >diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BaseAnnotationProcessorManager.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BaseAnnotationProcessorManager.java >index 658a99a..887f988 100644 >--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BaseAnnotationProcessorManager.java >+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BaseAnnotationProcessorManager.java >@@ -126,7 +126,7 @@ > > /** > * A single "round" of processing, in the sense implied in >- * {@link javax.lang.annotation.processing.Processor}. >+ * {@link javax.annotation.processing.Processor}. > * <p> > * The Java 6 Processor spec contains ambiguities about how processors that support "*" are > * handled. Eclipse tries to match Sun's implementation in javac. What that actually does is >diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchAnnotationProcessorManager.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchAnnotationProcessorManager.java >index d6c1a7f..941023d 100644 >--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchAnnotationProcessorManager.java >+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchAnnotationProcessorManager.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2005, 2007 IBM Corporation and others. >+ * Copyright (c) 2005, 2011 IBM Corporation 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 >@@ -25,7 +25,7 @@ > /** > * Java 6 annotation processor manager used when compiling from the command line > * or via the javax.tools.JavaCompiler interface. >- * @see org.eclipse.jdt.internal.compiler.apt.ide.dispatch.IdeAnnotationProcessorManager >+ * @see org.eclipse.jdt.internal.apt.pluggable.core.dispatch.IdeAnnotationProcessorManager > */ > public class BatchAnnotationProcessorManager extends BaseAnnotationProcessorManager > { >@@ -54,7 +54,7 @@ > /** > * Zero-arg constructor so this object can be easily created via reflection. > * A BatchAnnotationProcessorManager cannot be used until its >- * {@link #configure(Main, String[])} method has been called. >+ * {@link #configure(Object, String[])} method has been called. > */ > public BatchAnnotationProcessorManager() > { >@@ -77,7 +77,6 @@ > * If a -processor option was specified in command line arguments, > * parse it into a list of qualified classnames. > * @param commandLineArguments contains one string for every space-delimited token on the command line >- * @return a list of qualified classnames, or null if there was no -processor option. > */ > private void parseCommandLine(String[] commandLineArguments) { > List<String> commandLineProcessors = null; >diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchProcessingEnvImpl.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchProcessingEnvImpl.java >index ac70cde..b78042c 100644 >--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchProcessingEnvImpl.java >+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchProcessingEnvImpl.java >@@ -96,7 +96,7 @@ > > /** > * Parse the -A command line arguments so that they can be delivered to >- * processors with {@link ProcessingEnvironment#getOptions(). In Sun's Java 6 >+ * processors with {@link javax.annotation.processing.ProcessingEnvironment#getOptions()}. In Sun's Java 6 > * version of javac, unlike in the Java 5 apt tool, only the -A options are > * passed to processors, not the other command line options; that behavior > * is repeated here. >diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/ProcessorInfo.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/ProcessorInfo.java >index b9a463d..669c1e9 100644 >--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/ProcessorInfo.java >+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/ProcessorInfo.java >@@ -88,8 +88,6 @@ > * subsequent calls. > * > * @param annotations a set of annotation types >- * @param annotationTypes a set of names, which may use the wildcard "*", as described in >- * {@link Processor#getSupportedAnnotationTypes()}. > * @param result an empty modifiable set, which upon return will contain a subset of <code>annotations</code>, which may be empty but will not be null. > * @return true if the processor should be called on this round. > */ >diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/RoundEnvImpl.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/RoundEnvImpl.java >index f64cfff..8f44e4a 100644 >--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/RoundEnvImpl.java >+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/RoundEnvImpl.java >@@ -117,9 +117,9 @@ > > /** > * From the set of root elements and their enclosed elements, return the subset that are annotated >- * with {@code a}. If {@code a} is annotated with the {@link java.lang.annotations.Inherited} >+ * with {@code a}. If {@code a} is annotated with the {@link java.lang.annotation.Inherited} > * annotation, include those elements that inherit the annotation from their superclasses. >- * Note that {@link java.lang.annotations.Inherited} only applies to classes (i.e. TypeElements). >+ * Note that {@link java.lang.annotation.Inherited} only applies to classes (i.e. TypeElements). > */ > @Override > public Set<? extends Element> getElementsAnnotatedWith(TypeElement a) >@@ -146,7 +146,7 @@ > * For every type in types that is a class and that is annotated with anno, either directly or by inheritance, > * add that type to result. Recursively descend on each types's child classes as well. > * @param anno the compiler binding for an annotation type >- * @param types a set of types, not necessarily all classes >+ * @param type a type, not necessarily a class > * @param result must be a modifiable Set; will accumulate annotated classes > */ > private void addAnnotatedElements(ReferenceBinding anno, ReferenceBinding type, Set<Element> result) { >diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/AnnotationMirrorImpl.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/AnnotationMirrorImpl.java >index ad297f0..d961c78 100644 >--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/AnnotationMirrorImpl.java >+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/AnnotationMirrorImpl.java >@@ -121,7 +121,7 @@ > } > > /** >- * {@see Elements#getElementValuesWithDefaults()} >+ * @see javax.lang.model.util.Elements#getElementValuesWithDefaults(AnnotationMirror) > * @return all the members of this annotation mirror that have explicit or default > * values. > */ >@@ -280,7 +280,7 @@ > * and must be either a primitive type, String, Class, an enum constant, an annotation, or an > * array of any of those. Multidimensional arrays are not permitted. > * >- * @param annoValue the value as represented by {@link ElementValuePair#getValue()} >+ * @param actualValue the value as represented by {@link ElementValuePair#getValue()} > * @param actualType the return type of the corresponding {@link MethodBinding} > * @param expectedType the type that the reflective method invoker is expecting > * @return an object of the expected type representing the annotation member value, >diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ElementImpl.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ElementImpl.java >index 92ec14b..998e3d6 100644 >--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ElementImpl.java >+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ElementImpl.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2005, 2007 IBM Corporation and others. >+ * Copyright (c) 2005, 2011 IBM Corporation 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 >@@ -149,7 +149,7 @@ > /** > * Subclassed by VariableElementImpl, TypeElementImpl, and ExecutableElementImpl. > * This base implementation suffices for other types. >- * @see Elements#hides() >+ * @see Elements#hides > * @return true if this element hides {@code hidden} > */ > public boolean hides(Element hidden) >diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/IElementInfo.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/IElementInfo.java >index 40ed3da..7658f9f 100644 >--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/IElementInfo.java >+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/IElementInfo.java >@@ -15,7 +15,7 @@ > /** > * Additional information available for Elements that are implemented > * within the Eclipse APT framework. >- * @see javax.lang.model.Element >+ * @see javax.lang.model.element.Element > * @since 3.3 > */ > public interface IElementInfo { >diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/NoTypeImpl.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/NoTypeImpl.java >index 95a5df3..0117757 100644 >--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/NoTypeImpl.java >+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/NoTypeImpl.java >@@ -18,7 +18,7 @@ > > /** > * An implementation of NoType, which is used to represent certain psuedo-types. >- * @see NoType. >+ * @see NoType > */ > public class NoTypeImpl implements NoType, NullType > { >diff --git a/org.eclipse.jdt.compiler.tool.tests/.cvsignore b/org.eclipse.jdt.compiler.tool.tests/.cvsignore >deleted file mode 100644 >index c5e82d7..0000000 >--- a/org.eclipse.jdt.compiler.tool.tests/.cvsignore >+++ /dev/null >@@ -1 +0,0 @@ >-bin >\ No newline at end of file >diff --git a/org.eclipse.jdt.compiler.tool.tests/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.jdt.compiler.tool.tests/.settings/org.eclipse.core.runtime.prefs >new file mode 100644 >index 0000000..5a0ad22 >--- /dev/null >+++ b/org.eclipse.jdt.compiler.tool.tests/.settings/org.eclipse.core.runtime.prefs >@@ -0,0 +1,2 @@ >+eclipse.preferences.version=1 >+line.separator=\n >diff --git a/org.eclipse.jdt.compiler.tool.tests/META-INF/MANIFEST.MF b/org.eclipse.jdt.compiler.tool.tests/META-INF/MANIFEST.MF >index 327d9fe..8edd90d 100644 >--- a/org.eclipse.jdt.compiler.tool.tests/META-INF/MANIFEST.MF >+++ b/org.eclipse.jdt.compiler.tool.tests/META-INF/MANIFEST.MF >@@ -2,7 +2,7 @@ > Bundle-ManifestVersion: 2 > Bundle-Name: %pluginName > Bundle-SymbolicName: org.eclipse.jdt.compiler.tool.tests >-Bundle-Version: 1.0.100.qualifier >+Bundle-Version: 1.0.101.qualifier > Bundle-Vendor: %providerName > Bundle-Localization: plugin > Bundle-RequiredExecutionEnvironment: JavaSE-1.6 >diff --git a/org.eclipse.jdt.compiler.tool.tests/src/org/eclipse/jdt/compiler/tool/tests/AbstractCompilerToolTest.java b/org.eclipse.jdt.compiler.tool.tests/src/org/eclipse/jdt/compiler/tool/tests/AbstractCompilerToolTest.java >index cd6cbfe..cb26233 100644 >--- a/org.eclipse.jdt.compiler.tool.tests/src/org/eclipse/jdt/compiler/tool/tests/AbstractCompilerToolTest.java >+++ b/org.eclipse.jdt.compiler.tool.tests/src/org/eclipse/jdt/compiler/tool/tests/AbstractCompilerToolTest.java >@@ -12,6 +12,7 @@ > package org.eclipse.jdt.compiler.tool.tests; > > import java.io.File; >+import java.io.IOException; > import java.io.PrintWriter; > import java.util.ArrayList; > import java.util.List; >@@ -98,16 +99,24 @@ > if (manager == null) { > manager = COMPILER.getStandardFileManager(null, null, null); // will pick defaults up > } >- List<File> files = new ArrayList<File>(); >- String[] fileNames = arguments.fileNames; >- for (int i = 0, l = fileNames.length; i < l; i++) { >- if (fileNames[i].startsWith(OUTPUT_DIR)) { >- files.add(new File(fileNames[i])); >- } else { >- files.add(new File(OUTPUT_DIR + File.separator + fileNames[i])); >+ try { >+ List<File> files = new ArrayList<File>(); >+ String[] fileNames = arguments.fileNames; >+ for (int i = 0, l = fileNames.length; i < l; i++) { >+ if (fileNames[i].startsWith(OUTPUT_DIR)) { >+ files.add(new File(fileNames[i])); >+ } else { >+ files.add(new File(OUTPUT_DIR + File.separator + fileNames[i])); >+ } > } >- } >- CompilationTask task = COMPILER.getTask(out, arguments.standardJavaFileManager /* carry the null over */, new CompilerInvocationDiagnosticListener(err), arguments.options, null, manager.getJavaFileObjectsFromFiles(files)); >- return task.call(); >+ CompilationTask task = COMPILER.getTask(out, arguments.standardJavaFileManager /* carry the null over */, new CompilerInvocationDiagnosticListener(err), arguments.options, null, manager.getJavaFileObjectsFromFiles(files)); >+ return task.call(); >+ } finally { >+ try { >+ manager.close(); >+ } catch (IOException e) { >+ // nop >+ } >+ } > } > } >diff --git a/org.eclipse.jdt.compiler.tool.tests/src/org/eclipse/jdt/compiler/tool/tests/CompilerInvocationTests.java b/org.eclipse.jdt.compiler.tool.tests/src/org/eclipse/jdt/compiler/tool/tests/CompilerInvocationTests.java >index 60be95f..09a1689 100644 >--- a/org.eclipse.jdt.compiler.tool.tests/src/org/eclipse/jdt/compiler/tool/tests/CompilerInvocationTests.java >+++ b/org.eclipse.jdt.compiler.tool.tests/src/org/eclipse/jdt/compiler/tool/tests/CompilerInvocationTests.java >@@ -502,7 +502,9 @@ > remaining = remainingAsList.iterator(); > assertTrue("does not support -d option", javacStandardJavaFileManager.handleOption("-d", remaining)); > assertEquals("unexpected consumption rate", "remainder", remaining.next()); >+ javacStandardJavaFileManager.close(); > } >+ ecjStandardJavaFileManager.close(); > } > // https://bugs.eclipse.org/bugs/show_bug.cgi?id=226918 > // options consumption - check consumption rate on supported zero-args options >@@ -525,6 +527,7 @@ > assertEquals("unexpected consumption rate", REMAINDER, remaining.next()); > } > } >+ ecjStandardJavaFileManager.close(); > } > // https://bugs.eclipse.org/bugs/show_bug.cgi?id=226918 > // options consumption - check consumption rate on supported one-arg options >@@ -540,6 +543,7 @@ > assertEquals("unexpected consumption rate", REMAINDER, remaining.next()); > } > } >+ ecjStandardJavaFileManager.close(); > } > // tests #10-11 show that ecj throws a RuntimeException when encountering a wrong > // encoding in its parameters, while the default compiler swallows it silently >diff --git a/org.eclipse.jdt.compiler.tool.tests/src/org/eclipse/jdt/compiler/tool/tests/CompilerToolTests.java b/org.eclipse.jdt.compiler.tool.tests/src/org/eclipse/jdt/compiler/tool/tests/CompilerToolTests.java >index 84e2c1f..bf44e40 100644 >--- a/org.eclipse.jdt.compiler.tool.tests/src/org/eclipse/jdt/compiler/tool/tests/CompilerToolTests.java >+++ b/org.eclipse.jdt.compiler.tool.tests/src/org/eclipse/jdt/compiler/tool/tests/CompilerToolTests.java >@@ -19,6 +19,7 @@ > import java.io.StringWriter; > import java.nio.charset.Charset; > import java.util.ArrayList; >+import java.util.Collections; > import java.util.HashSet; > import java.util.Iterator; > import java.util.List; >@@ -604,7 +605,7 @@ > assertTrue("delete failed", inputFile.delete()); > } > >- public void testCompilerOneClassWithEclipseCompiler4() { >+ public void testCompilerOneClassWithEclipseCompiler4() throws IOException { > JavaCompiler systemCompiler = ToolProvider.getSystemJavaCompiler(); > if (systemCompiler == null) { > System.out.println("No system java compiler available"); >@@ -653,6 +654,7 @@ > } > // check that the .class file exist for X > assertTrue("delete failed", inputFile.delete()); >+ manager.close(); > } > > public void testCompilerOneClassWithEclipseCompiler5() { >@@ -869,6 +871,7 @@ > builder.append(name.substring(lastIndexOf + 1)); > } > assertEquals("Wrong contents", "X.java", String.valueOf(builder)); >+ fileManager.close(); > } catch (IOException e) { > e.printStackTrace(); > } >@@ -934,15 +937,17 @@ > Iterable<? extends JavaFileObject> compilationUnits = fileManager.list(sourceLoc, "", fileTypes, true); > > Iterator<? extends JavaFileObject> it = compilationUnits.iterator(); >- StringBuilder builder = new StringBuilder(); >+ List<String> names = new ArrayList<String>(); > while (it.hasNext()) { > JavaFileObject next = it.next(); > String name = next.getName(); > name = name.replace('\\', '/'); > int lastIndexOf = name.lastIndexOf('/'); >- builder.append(name.substring(lastIndexOf + 1)); >+ names.add(name.substring(lastIndexOf + 1)); > } >- assertEquals("Wrong contents", "X2.javaX.java", String.valueOf(builder)); >+ Collections.sort(names); >+ assertEquals("Wrong contents", "[X.java, X2.java]", names.toString()); >+ fileManager.close(); > } catch (IOException e) { > e.printStackTrace(); > } >diff --git a/org.eclipse.jdt.compiler.tool.tests/test.xml b/org.eclipse.jdt.compiler.tool.tests/test.xml >index ed77e1f..50a300d 100644 >--- a/org.eclipse.jdt.compiler.tool.tests/test.xml >+++ b/org.eclipse.jdt.compiler.tool.tests/test.xml >@@ -1,6 +1,7 @@ >-<?xml version="1.0"?> >- <!-- >- Copyright (c) 2006, 2009 IBM Corporation and others. >+<?xml version="1.0" encoding="UTF-8"?> >+ >+<!-- >+ Copyright (c) 2006, 2011 IBM Corporation 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 >diff --git a/org.eclipse.jdt.compiler.tool/.cvsignore b/org.eclipse.jdt.compiler.tool/.cvsignore >deleted file mode 100644 >index c5e82d7..0000000 >--- a/org.eclipse.jdt.compiler.tool/.cvsignore >+++ /dev/null >@@ -1 +0,0 @@ >-bin >\ No newline at end of file >diff --git a/org.eclipse.jdt.compiler.tool/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.jdt.compiler.tool/.settings/org.eclipse.core.runtime.prefs >new file mode 100644 >index 0000000..5a0ad22 >--- /dev/null >+++ b/org.eclipse.jdt.compiler.tool/.settings/org.eclipse.core.runtime.prefs >@@ -0,0 +1,2 @@ >+eclipse.preferences.version=1 >+line.separator=\n >diff --git a/org.eclipse.jdt.compiler.tool/META-INF/MANIFEST.MF b/org.eclipse.jdt.compiler.tool/META-INF/MANIFEST.MF >index 65f787c..0abadb8 100644 >--- a/org.eclipse.jdt.compiler.tool/META-INF/MANIFEST.MF >+++ b/org.eclipse.jdt.compiler.tool/META-INF/MANIFEST.MF >@@ -2,7 +2,7 @@ > Bundle-ManifestVersion: 2 > Bundle-Name: %fragmentName > Bundle-SymbolicName: org.eclipse.jdt.compiler.tool;singleton:=true >-Bundle-Version: 1.0.100.qualifier >+Bundle-Version: 1.0.101.qualifier > Bundle-Vendor: %providerName > Bundle-Localization: compiler_tool_fragment > Bundle-RequiredExecutionEnvironment: JavaSE-1.6 >diff --git a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/Options.java b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/Options.java >index 7b29f99..2ba27f4 100644 >--- a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/Options.java >+++ b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/Options.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2006, 2010 IBM Corporation and others. >+ * Copyright (c) 2006, 2012 IBM Corporation 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 >@@ -41,7 +41,6 @@ > Options.ZERO_ARGUMENT_OPTIONS.add("-inlineJSR");//$NON-NLS-1$ > Options.ZERO_ARGUMENT_OPTIONS.add("-g");//$NON-NLS-1$ > Options.ZERO_ARGUMENT_OPTIONS.add("-g:none");//$NON-NLS-1$ >- Options.ZERO_ARGUMENT_OPTIONS.add("-nowarn");//$NON-NLS-1$ > Options.ZERO_ARGUMENT_OPTIONS.add("-warn:none");//$NON-NLS-1$ > Options.ZERO_ARGUMENT_OPTIONS.add("-preserveAllLocals");//$NON-NLS-1$ > Options.ZERO_ARGUMENT_OPTIONS.add("-enableJavadoc");//$NON-NLS-1$ >@@ -243,6 +242,28 @@ > return 0; > } > } >+ if (option.startsWith("-nowarn")) {//$NON-NLS-1$ >+ switch (option.length()) { >+ case 7: >+ return 0; >+ case 8: >+ return -1; >+ default: >+ int foldersStart = option.indexOf('[') + 1; >+ int foldersEnd = option.lastIndexOf(']'); >+ if (foldersStart <= 8 || foldersEnd == -1 >+ || foldersStart > foldersEnd >+ || foldersEnd < option.length() - 1) { >+ return -1; >+ } >+ String folders = option.substring(foldersStart, foldersEnd); >+ if (folders.length() > 0) { >+ return 0; >+ } else { >+ return -1; >+ } >+ } >+ } > if (option.startsWith("-J")//$NON-NLS-1$ > || option.startsWith("-X")//$NON-NLS-1$ > || option.startsWith("-A")) {//$NON-NLS-1$ >diff --git a/org.eclipse.jdt.core.tests.builder/.cvsignore b/org.eclipse.jdt.core.tests.builder/.cvsignore >deleted file mode 100644 >index c5e82d7..0000000 >--- a/org.eclipse.jdt.core.tests.builder/.cvsignore >+++ /dev/null >@@ -1 +0,0 @@ >-bin >\ No newline at end of file >diff --git a/org.eclipse.jdt.core.tests.builder/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.jdt.core.tests.builder/.settings/org.eclipse.core.runtime.prefs >new file mode 100644 >index 0000000..5a0ad22 >--- /dev/null >+++ b/org.eclipse.jdt.core.tests.builder/.settings/org.eclipse.core.runtime.prefs >@@ -0,0 +1,2 @@ >+eclipse.preferences.version=1 >+line.separator=\n >diff --git a/org.eclipse.jdt.core.tests.builder/META-INF/MANIFEST.MF b/org.eclipse.jdt.core.tests.builder/META-INF/MANIFEST.MF >index c1bf0ee..7537be0 100644 >--- a/org.eclipse.jdt.core.tests.builder/META-INF/MANIFEST.MF >+++ b/org.eclipse.jdt.core.tests.builder/META-INF/MANIFEST.MF >@@ -2,7 +2,7 @@ > Bundle-ManifestVersion: 2 > Bundle-Name: %pluginName > Bundle-SymbolicName: org.eclipse.jdt.core.tests.builder; singleton:=true >-Bundle-Version: 3.8.0.qualifier >+Bundle-Version: 3.8.1.qualifier > Bundle-ClassPath: jdtcoretestsbuilder.jar > Bundle-Vendor: %providerName > Bundle-Localization: plugin >diff --git a/org.eclipse.jdt.core.tests.builder/plugin.xml b/org.eclipse.jdt.core.tests.builder/plugin.xml >index b188847..b1ae538 100644 >--- a/org.eclipse.jdt.core.tests.builder/plugin.xml >+++ b/org.eclipse.jdt.core.tests.builder/plugin.xml >@@ -1,5 +1,6 @@ > <?xml version="1.0" encoding="UTF-8"?> >-<?eclipse version="3.0"?> <!-- >+<?eclipse version="3.0"?> >+<!-- > Copyright (c) 2002, 2009 IBM Corporation and others. > All rights reserved. This program and the accompanying materials > are made available under the terms of the Eclipse Public License v1.0 >diff --git a/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/AnnotationDependencyTests.java b/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/AnnotationDependencyTests.java >index 38f0a99..949038d 100644 >--- a/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/AnnotationDependencyTests.java >+++ b/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/AnnotationDependencyTests.java >@@ -8,13 +8,24 @@ > * Contributors: > * Walter Harley (eclipse@cafewalter.com) - initial implementation > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contribution for bug 365992 - [builder] [null] Change of nullness for a parameter doesn't trigger a build for the files that call the method > *******************************************************************************/ > package org.eclipse.jdt.core.tests.builder; >+ >+import java.io.File; >+import java.io.IOException; > > import junit.framework.Test; > > import org.eclipse.core.resources.IMarker; >+import org.eclipse.core.runtime.FileLocator; > import org.eclipse.core.runtime.IPath; >+import org.eclipse.core.runtime.Path; >+import org.eclipse.core.runtime.Platform; >+import org.eclipse.jdt.core.IClasspathEntry; >+import org.eclipse.jdt.core.IJavaProject; >+import org.eclipse.jdt.core.JavaCore; >+import org.eclipse.jdt.core.JavaModelException; > import org.eclipse.jdt.core.compiler.CategorizedProblem; > import org.eclipse.jdt.core.tests.util.Util; > >@@ -127,6 +138,20 @@ > env.addClass(this.srcRoot, "p1", "AnnoClass", annoCode); > } > >+ void setupProjectForNullAnnotations() throws IOException, JavaModelException { >+ // add the org.eclipse.jdt.annotation library (bin/ folder or jar) to the project: >+ File bundleFile = FileLocator.getBundleFile(Platform.getBundle("org.eclipse.jdt.annotation")); >+ String annotationsLib = bundleFile.isDirectory() ? bundleFile.getPath()+"/bin" : bundleFile.getPath(); >+ IJavaProject javaProject = env.getJavaProject(this.projectPath); >+ IClasspathEntry[] rawClasspath = javaProject.getRawClasspath(); >+ int len = rawClasspath.length; >+ System.arraycopy(rawClasspath, 0, rawClasspath = new IClasspathEntry[len+1], 0, len); >+ rawClasspath[len] = JavaCore.newLibraryEntry(new Path(annotationsLib), null, null); >+ javaProject.setRawClasspath(rawClasspath, null); >+ >+ javaProject.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED); >+ } >+ > /** > * This test makes sure that changing an annotation on type A causes type B > * to be recompiled, if B references A. See http://bugs.eclipse.org/149768 >@@ -1371,4 +1396,115 @@ > // verify that B was recompiled > expectingUniqueCompiledClasses(new String[] { "p1.A", "p1.B" }); > } >+ >+ // Bug 365992 - [builder] [null] Change of nullness for a parameter doesn't trigger a build for the files that call the method >+ public void testParameterAnnotationDependency01() throws JavaModelException, IOException { >+ // prepare the project: >+ setupProjectForNullAnnotations(); >+ >+ String test1Code = "package p1;\n" + >+ "public class Test1 {\n" + >+ " public void foo() {\n" + >+ " new Test2().bar(null);\n" + >+ " }\n" + >+ "}"; >+ String test2Code = "package p1;\n" + >+ "public class Test2 {\n" + >+ " public void bar(String str) {}\n" + >+ "}"; >+ >+ IPath test1Path = env.addClass( this.srcRoot, "p1", "Test1", test1Code ); >+ env.addClass( this.srcRoot, "p1", "Test2", test2Code ); >+ >+ fullBuild( this.projectPath ); >+ expectingNoProblems(); >+ >+ // edit Test2 to add @NonNull annotation (changes number of annotations) >+ String test2CodeB = "package p1;\n" + >+ "import org.eclipse.jdt.annotation.NonNull;\n" + >+ "public class Test2 {\n" + >+ " public void bar(@NonNull String str) {}\n" + >+ "}"; >+ env.addClass( this.srcRoot, "p1", "Test2", test2CodeB ); >+ incrementalBuild( this.projectPath ); >+ expectingProblemsFor(test1Path, >+ "Problem : Type mismatch: required \'@NonNull String\' but the provided value is null [ resource : </Project/src/p1/Test1.java> range : <81,85> category : <90> severity : <2>]"); >+ >+ // verify that Test1 was recompiled >+ expectingUniqueCompiledClasses(new String[] { "p1.Test1", "p1.Test2" }); >+ >+ // fix error by changing to @Nullable (change is only in an annotation name) >+ String test2CodeC = "package p1;\n" + >+ "import org.eclipse.jdt.annotation.Nullable;\n" + >+ "public class Test2 {\n" + >+ " public void bar(@Nullable String str) {}\n" + >+ "}"; >+ env.addClass( this.srcRoot, "p1", "Test2", test2CodeC ); >+ incrementalBuild( this.projectPath ); >+ expectingNoProblems(); >+ >+ // verify that Test1 was recompiled >+ expectingUniqueCompiledClasses(new String[] { "p1.Test1", "p1.Test2" }); >+ } >+ >+ // Bug 365992 - [builder] [null] Change of nullness for a parameter doesn't trigger a build for the files that call the method >+ // Bug 366341 - Incremental compiler fails to detect right scope for annotation related code changes >+ public void testReturnAnnotationDependency01() throws JavaModelException, IOException { >+ // prepare the project: >+ setupProjectForNullAnnotations(); >+ >+ String test1Code = "package p1;\n" + >+ "import org.eclipse.jdt.annotation.NonNull;\n" + >+ "public class Test1 {\n" + >+ " public @NonNull Object foo() {\n" + >+ " return new Test2().bar();\n" + >+ " }\n" + >+ "}"; >+ String test2Code = "package p1;\n" + >+ "import org.eclipse.jdt.annotation.NonNull;\n" + >+ "public class Test2 {\n" + >+ " public @NonNull Object bar() { return this; }\n" + >+ "}"; >+ >+ IPath test1Path = env.addClass( this.srcRoot, "p1", "Test1", test1Code ); >+ env.addClass( this.srcRoot, "p1", "Test2", test2Code ); >+ >+ fullBuild( this.projectPath ); >+ expectingNoProblems(); >+ >+ // edit Test2 to replace annotation >+ String test2CodeB = "package p1;\n" + >+ "import org.eclipse.jdt.annotation.Nullable;\n" + >+ "public class Test2 {\n" + >+ " public @Nullable Object bar() { return null; }\n" + >+ "}"; >+ env.addClass( this.srcRoot, "p1", "Test2", test2CodeB ); >+ incrementalBuild( this.projectPath ); >+ expectingProblemsFor(test1Path, >+ "Problem : Type mismatch: required \'@NonNull Object\' but the provided value can be null [ resource : </Project/src/p1/Test1.java> range : <126,143> category : <90> severity : <2>]"); >+ >+ // verify that Test1 was recompiled >+ expectingUniqueCompiledClasses(new String[] { "p1.Test1", "p1.Test2" }); >+ >+ // remove annotation, error changes from can be null to unknown nullness >+ String test2CodeC = "package p1;\n" + >+ "public class Test2 {\n" + >+ " public Object bar() { return null; }\n" + >+ "}"; >+ env.addClass( this.srcRoot, "p1", "Test2", test2CodeC ); >+ incrementalBuild( this.projectPath ); >+ expectingProblemsFor(test1Path, >+ "Problem : Potential type mismatch: required \'@NonNull Object\' but nullness of the provided value is unknown [ resource : </Project/src/p1/Test1.java> range : <126,143> category : <90> severity : <1>]"); >+ >+ // verify that Test1 was recompiled >+ expectingUniqueCompiledClasses(new String[] { "p1.Test1", "p1.Test2" }); >+ >+ // back to initial OK version (re-add @NonNull annotation) >+ env.addClass( this.srcRoot, "p1", "Test2", test2Code ); >+ incrementalBuild( this.projectPath ); >+ expectingNoProblems(); >+ >+ // verify that Test1 was recompiled >+ expectingUniqueCompiledClasses(new String[] { "p1.Test1", "p1.Test2" }); >+ } > } >diff --git a/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/ErrorsTests.java b/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/ErrorsTests.java >index f11a112..93ead6b 100644 >--- a/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/ErrorsTests.java >+++ b/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/ErrorsTests.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -17,14 +17,17 @@ > import java.io.StringWriter; > import java.util.Arrays; > import java.util.Comparator; >+import java.util.Hashtable; > >-import junit.framework.*; >+import junit.framework.Test; > > import org.eclipse.core.resources.IFile; > import org.eclipse.core.resources.IMarker; > import org.eclipse.core.resources.IResource; > import org.eclipse.core.runtime.CoreException; > import org.eclipse.core.runtime.IPath; >+import org.eclipse.core.runtime.Path; >+import org.eclipse.jdt.core.IClasspathAttribute; > import org.eclipse.jdt.core.IJavaProject; > import org.eclipse.jdt.core.IRegion; > import org.eclipse.jdt.core.JavaCore; >@@ -43,6 +46,8 @@ > * Basic errors tests of the image builder. > */ > public class ErrorsTests extends BuilderTests { >+ private static final IClasspathAttribute ATTR_IGNORE_OPTIONAL_PROBLEMS_TRUE = JavaCore.newClasspathAttribute(IClasspathAttribute.IGNORE_OPTIONAL_PROBLEMS, "true"); >+ > private static final Comparator COMPARATOR = new Comparator() { > public int compare(Object o1, Object o2) { > IResource resource1 = (IResource) o1; >@@ -441,4 +446,199 @@ > writer.close(); > return Util.convertToIndependantLineDelimiter(String.valueOf(stringWriter)); > } >+ >+// ignore optional errors >+public void test0108() throws JavaModelException { >+ Hashtable options = JavaCore.getOptions(); >+ Hashtable newOptions = JavaCore.getOptions(); >+ newOptions.put(JavaCore.COMPILER_PB_UNUSED_LOCAL, JavaCore.ERROR); >+ >+ JavaCore.setOptions(newOptions); >+ >+ IPath projectPath = env.addProject("P"); >+ env.addExternalJars(projectPath, Util.getJavaClassLibs()); >+ >+ // remove old package fragment root so that names don't collide >+ env.removePackageFragmentRoot(projectPath, ""); >+ >+ env.setOutputFolder(projectPath, "bin"); >+ IPath root = new Path("/P/src"); >+ env.addEntry(projectPath, JavaCore.newSourceEntry(root, null, null, >+ null, new IClasspathAttribute[] { ATTR_IGNORE_OPTIONAL_PROBLEMS_TRUE })); >+ >+ env.addClass(root, "p", "X", >+ "package p;\n" + >+ "public class X {\n" + >+ " public void foo() {\n" + >+ " int i;\n" + >+ " }\n" + >+ "}"); >+ >+ fullBuild(projectPath); >+ expectingNoProblems(); >+ >+ JavaCore.setOptions(options); >+} >+ >+// two different source folders ignore only from one >+public void test0109() throws JavaModelException { >+ Hashtable options = JavaCore.getOptions(); >+ Hashtable newOptions = JavaCore.getOptions(); >+ newOptions.put(JavaCore.COMPILER_PB_UNUSED_LOCAL, JavaCore.ERROR); >+ >+ JavaCore.setOptions(newOptions); >+ >+ IPath projectPath = env.addProject("P"); >+ env.addExternalJars(projectPath, Util.getJavaClassLibs()); >+ >+ // remove old package fragment root so that names don't collide >+ env.removePackageFragmentRoot(projectPath, ""); >+ >+ env.setOutputFolder(projectPath, "bin"); >+ IPath src = new Path("/P/src"); >+ IPath src2 = new Path("/P/src2"); >+ env.addEntry(projectPath, JavaCore.newSourceEntry(src, null, null, >+ null, new IClasspathAttribute[] { ATTR_IGNORE_OPTIONAL_PROBLEMS_TRUE })); >+ env.addEntry(projectPath, JavaCore.newSourceEntry(src2)); >+ >+ env.addClass(src, "p", "X", >+ "package p;\n" + >+ "public class X {\n" + >+ " public void foo() {\n" + >+ " int i;\n" + >+ " }\n" + >+ "}"); >+ >+ IPath classY = env.addClass(src2, "q", "Y", >+ "package q;\n" + >+ "public class Y {\n" + >+ " public void foo() {\n" + >+ " int i;\n" + >+ " }\n" + >+ "}"); >+ >+ fullBuild(projectPath); >+ expectingNoProblemsFor(src); >+ expectingOnlySpecificProblemFor(classY, new Problem("q", "The value of the local variable i is not used", classY, 55, 56, CategorizedProblem.CAT_UNNECESSARY_CODE, IMarker.SEVERITY_ERROR)); >+ >+ JavaCore.setOptions(options); >+} >+ >+// two different source folders ignore from both >+public void test0110() throws JavaModelException { >+ Hashtable options = JavaCore.getOptions(); >+ Hashtable newOptions = JavaCore.getOptions(); >+ newOptions.put(JavaCore.COMPILER_PB_UNUSED_LOCAL, JavaCore.ERROR); >+ >+ JavaCore.setOptions(newOptions); >+ >+ IPath projectPath = env.addProject("P"); >+ env.addExternalJars(projectPath, Util.getJavaClassLibs()); >+ >+ // remove old package fragment root so that names don't collide >+ env.removePackageFragmentRoot(projectPath, ""); >+ >+ env.setOutputFolder(projectPath, "bin"); >+ IPath src = new Path("/P/src"); >+ IPath src2 = new Path("/P/src2"); >+ env.addEntry(projectPath, JavaCore.newSourceEntry(src, null, null, >+ null, new IClasspathAttribute[] { ATTR_IGNORE_OPTIONAL_PROBLEMS_TRUE })); >+ env.addEntry(projectPath, JavaCore.newSourceEntry(src2, null, null, >+ null, new IClasspathAttribute[] { ATTR_IGNORE_OPTIONAL_PROBLEMS_TRUE })); >+ >+ env.addClass(src, "p", "X", >+ "package p;\n" + >+ "public class X {\n" + >+ " public void foo() {\n" + >+ " int i;\n" + >+ " }\n" + >+ "}"); >+ >+ env.addClass(src2, "q", "Y", >+ "package q;\n" + >+ "public class Y {\n" + >+ " public void foo() {\n" + >+ " int i;\n" + >+ " }\n" + >+ "}"); >+ >+ fullBuild(projectPath); >+ expectingNoProblems(); >+ >+ JavaCore.setOptions(options); >+} >+ >+//non-optional errors cannot be ignored >+public void test0111() throws JavaModelException { >+ Hashtable options = JavaCore.getOptions(); >+ Hashtable newOptions = JavaCore.getOptions(); >+ newOptions.put(JavaCore.COMPILER_PB_UNUSED_LOCAL, JavaCore.ERROR); >+ >+ JavaCore.setOptions(newOptions); >+ >+ IPath projectPath = env.addProject("P"); >+ env.addExternalJars(projectPath, Util.getJavaClassLibs()); >+ >+ // remove old package fragment root so that names don't collide >+ env.removePackageFragmentRoot(projectPath, ""); >+ >+ env.setOutputFolder(projectPath, "bin"); >+ IPath root = new Path("/P/src"); >+ env.addEntry(projectPath, JavaCore.newSourceEntry(root, null, null, >+ null, new IClasspathAttribute[] { ATTR_IGNORE_OPTIONAL_PROBLEMS_TRUE })); >+ >+ IPath classX = env.addClass(root, "p", "X", >+ "package p;\n" + >+ "public class X {\n" + >+ " public void foo() {\n" + >+ " int i;\n" + >+ " }\n" + >+ " public void bar() {\n" + >+ " a++;\n" + >+ " }\n" + >+ "}"); >+ >+ fullBuild(projectPath); >+ expectingOnlySpecificProblemFor(classX, new Problem("p", "a cannot be resolved to a variable", classX, 84, 85, CategorizedProblem.CAT_MEMBER, IMarker.SEVERITY_ERROR)); >+ >+ JavaCore.setOptions(options); >+} >+ >+//task tags cannot be ignored >+public void test0112() throws JavaModelException { >+ Hashtable options = JavaCore.getOptions(); >+ Hashtable newOptions = JavaCore.getOptions(); >+ newOptions.put(JavaCore.COMPILER_PB_UNUSED_LOCAL, JavaCore.ERROR); >+ newOptions.put(JavaCore.COMPILER_TASK_TAGS, "TODO"); >+ newOptions.put(JavaCore.COMPILER_TASK_PRIORITIES, "NORMAL"); >+ >+ JavaCore.setOptions(newOptions); >+ >+ IPath projectPath = env.addProject("P"); >+ env.addExternalJars(projectPath, Util.getJavaClassLibs()); >+ >+ // remove old package fragment root so that names don't collide >+ env.removePackageFragmentRoot(projectPath, ""); >+ >+ env.setOutputFolder(projectPath, "bin"); >+ IPath root = new Path("/P/src"); >+ env.addEntry(projectPath, JavaCore.newSourceEntry(root, null, null, >+ null, new IClasspathAttribute[] { ATTR_IGNORE_OPTIONAL_PROBLEMS_TRUE })); >+ >+ IPath classX = env.addClass(root, "p", "X", >+ "package p;\n" + >+ "public class X {\n" + >+ " public void foo() {\n" + >+ " int i;\n" + >+ " }\n" + >+ " public void bar() {\n" + >+ " // TODO nothing\n" + >+ " }\n" + >+ "}"); >+ >+ fullBuild(projectPath); >+ expectingOnlySpecificProblemFor(classX, new Problem("p", "TODO nothing", classX, 87, 99, -1, IMarker.SEVERITY_ERROR)); >+ >+ JavaCore.setOptions(options); >+} > } >diff --git a/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/IncrementalTests.java b/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/IncrementalTests.java >index 7b36543..84b904d 100644 >--- a/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/IncrementalTests.java >+++ b/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/IncrementalTests.java >@@ -1053,4 +1053,37 @@ > JavaCore.setOptions(options); > } > } >+ >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=364450 >+ // Incremental build should not generate buildpath error >+ // NOT generated by full build. >+ public void testBug364450() throws JavaModelException { >+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$ >+ env.addExternalJars(projectPath, Util.getJavaClassLibs()); >+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$ >+ >+ IPath wPath = env.addClass(projectPath, "w", "W", //$NON-NLS-1$ //$NON-NLS-2$ >+ "package w;\n" + >+ "public class W {\n" + >+ " private w.I i;}"); //$NON-NLS-1$ >+ >+ IPath aPath = env.addClass(projectPath, "a", "A", //$NON-NLS-1$ //$NON-NLS-2$ >+ "package a;\n" + >+ "import w.I;\n" + >+ "import w.W;\n" + >+ "public class A {}"); //$NON-NLS-1$ >+ >+ fullBuild(projectPath); >+ expectingSpecificProblemFor(wPath, new Problem("W", "w.I cannot be resolved to a type", wPath, 37, 40, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$ >+ expectingSpecificProblemFor(aPath, new Problem("A", "The import w.I cannot be resolved", aPath, 18, 21, CategorizedProblem.CAT_IMPORT, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$ >+ >+ aPath = env.addClass(projectPath, "a", "A", //$NON-NLS-1$ //$NON-NLS-2$ >+ "package a;\n" + >+ "import w.I;\n" + >+ "import w.W;\n" + >+ "public class A {}"); //$NON-NLS-1$ >+ >+ incrementalBuild(projectPath); >+ expectingSpecificProblemFor(aPath, new Problem("A", "The import w.I cannot be resolved", aPath, 18, 21, CategorizedProblem.CAT_IMPORT, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$ >+ } > } >diff --git a/org.eclipse.jdt.core.tests.builder/test.xml b/org.eclipse.jdt.core.tests.builder/test.xml >index b220a2b..6a40940 100644 >--- a/org.eclipse.jdt.core.tests.builder/test.xml >+++ b/org.eclipse.jdt.core.tests.builder/test.xml >@@ -1,6 +1,7 @@ >-<?xml version="1.0"?> >- <!-- >- Copyright (c) 2002, 2009 IBM Corporation and others. >+<?xml version="1.0" encoding="UTF-8"?> >+ >+<!-- >+ Copyright (c) 2002, 2011 IBM Corporation 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 >diff --git a/org.eclipse.jdt.core.tests.compiler/.cvsignore b/org.eclipse.jdt.core.tests.compiler/.cvsignore >deleted file mode 100644 >index c5e82d7..0000000 >--- a/org.eclipse.jdt.core.tests.compiler/.cvsignore >+++ /dev/null >@@ -1 +0,0 @@ >-bin >\ No newline at end of file >diff --git a/org.eclipse.jdt.core.tests.compiler/.settings/org.eclipse.core.resources.prefs b/org.eclipse.jdt.core.tests.compiler/.settings/org.eclipse.core.resources.prefs >new file mode 100644 >index 0000000..0f2c123 >--- /dev/null >+++ b/org.eclipse.jdt.core.tests.compiler/.settings/org.eclipse.core.resources.prefs >@@ -0,0 +1,3 @@ >+#Thu Sep 08 10:09:40 EDT 2011 >+eclipse.preferences.version=1 >+encoding//src/org/eclipse/jdt/core/tests/compiler/regression/ScannerTest.java=UTF-8 >diff --git a/org.eclipse.jdt.core.tests.compiler/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.jdt.core.tests.compiler/.settings/org.eclipse.core.runtime.prefs >new file mode 100644 >index 0000000..5a0ad22 >--- /dev/null >+++ b/org.eclipse.jdt.core.tests.compiler/.settings/org.eclipse.core.runtime.prefs >@@ -0,0 +1,2 @@ >+eclipse.preferences.version=1 >+line.separator=\n >diff --git a/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF b/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF >index d89db69..111b32f 100644 >--- a/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF >+++ b/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF >@@ -2,7 +2,7 @@ > Bundle-ManifestVersion: 2 > Bundle-Name: %pluginName > Bundle-SymbolicName: org.eclipse.jdt.core.tests.compiler >-Bundle-Version: 3.8.0.qualifier >+Bundle-Version: 3.8.1.qualifier > Bundle-ClassPath: jdtcoretestscompiler.jar > Bundle-Vendor: %providerName > Bundle-Localization: plugin >@@ -18,5 +18,6 @@ > org.eclipse.jdt.core;bundle-version="[3.7.0,4.0.0)", > org.eclipse.core.runtime;bundle-version="[3.2.0,4.0.0)", > org.eclipse.test.performance;bundle-version="[3.1.0,4.0.0)", >- org.eclipse.core.resources;bundle-version="[3.2.0,4.0.0)" >+ org.eclipse.core.resources;bundle-version="[3.2.0,4.0.0)", >+ org.eclipse.jdt.annotation;bundle-version="[1.0.0,2.0.0)" > Bundle-RequiredExecutionEnvironment: J2SE-1.4 >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/AnnotationDietRecoveryTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/AnnotationDietRecoveryTest.java >index 695aa46..6e8ba36 100644 >--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/AnnotationDietRecoveryTest.java >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/AnnotationDietRecoveryTest.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2008 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -1909,4 +1909,59 @@ > expectedCompletionDietUnitToString, > testName); > } >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=366003 >+public void test0041() { >+ >+ String s = >+ "package snippet;\n" + >+ "public class Bug366003 {\n" + >+ " void foo(Object o1){}\n" + >+ " @Blah org.User(@Bla String str){}\n" + >+ "}\n"; >+ >+ String expectedDietUnitToString = >+ "package snippet;\n" + >+ "public class Bug366003 {\n" + >+ " public Bug366003() {\n" + >+ " }\n" + >+ " void foo(Object o1) {\n" + >+ " }\n" + >+ " @Blah User(@Bla String str) {\n" + >+ " }\n" + >+ "}\n"; >+ >+ String expectedDietPlusBodyUnitToString = >+ "package snippet;\n" + >+ "public class Bug366003 {\n" + >+ " public Bug366003() {\n" + >+ " super();\n" + >+ " }\n" + >+ " void foo(Object o1) {\n" + >+ " }\n" + >+ " @Blah User(@Bla String str) {\n" + >+ " }\n" + >+ "}\n"; >+ >+ String expectedFullUnitToString = expectedDietUnitToString; >+ >+ String expectedCompletionDietUnitToString = >+ "package snippet;\n" + >+ "public class Bug366003 {\n" + >+ " public Bug366003() {\n" + >+ " }\n" + >+ " void foo(Object o1) {\n" + >+ " }\n" + >+ " User(@Bla String str) {\n" + >+ " }\n" + >+ "}\n"; >+ >+ String testName = "<annotation recovery>"; >+ checkParse( >+ s.toCharArray(), >+ expectedDietUnitToString, >+ expectedDietPlusBodyUnitToString, >+ expectedFullUnitToString, >+ expectedCompletionDietUnitToString, >+ testName); >+} > } >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/SelectionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/SelectionTest.java >index 816aac9..a11f6ac 100644 >--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/SelectionTest.java >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/SelectionTest.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -2448,4 +2448,66 @@ > expectedReplacedSource, > testName); > } >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=291040 >+public void test56() { >+ >+ String str = >+ "class X {\n" + >+ " void foo() {\n" + >+ " new X(null) {\n" + >+ " void goo() {\n" + >+ " new X(zoo()) {\n" + >+ " void voo() {\n" + >+ " }\n" + >+ " };\n" + >+ " }\n" + >+ "\n" + >+ " Object zoo() {\n" + >+ " return null;\n" + >+ " }\n" + >+ " };\n" + >+ " }\n" + >+ "\n" + >+ " X(Object k) {\n" + >+ " }\n" + >+ "}\n"; >+ >+ String selection = "zoo"; >+ >+ String expectedCompletionNodeToString = "<SelectOnMessageSend:zoo()>"; >+ >+ String completionIdentifier = "zoo"; >+ String expectedUnitDisplayString = >+ "class X {\n" + >+ " void foo() {\n" + >+ " new X(null) {\n" + >+ " void goo() {\n" + >+ " new X(<SelectOnMessageSend:zoo()>) {\n" + >+ " void voo() {\n" + >+ " }\n" + >+ " };\n" + >+ " }\n" + >+ " Object zoo() {\n" + >+ " }\n" + >+ " };\n" + >+ " }\n" + >+ " X(Object k) {\n" + >+ " }\n" + >+ "}\n"; >+ String expectedReplacedSource = "zoo()"; >+ String testName = "<select>"; >+ >+ int selectionStart = str.indexOf(selection); >+ int selectionEnd = str.indexOf(selection) + selection.length() - 1; >+ >+ this.checkMethodParse( >+ str.toCharArray(), >+ selectionStart, >+ selectionEnd, >+ expectedCompletionNodeToString, >+ expectedUnitDisplayString, >+ completionIdentifier, >+ expectedReplacedSource, >+ testName); >+} > } >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java >index 62da41c..8241a53 100644 >--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java >@@ -21,6 +21,7 @@ > import java.io.InputStream; > import java.io.InputStreamReader; > import java.io.PrintWriter; >+import java.net.URL; > import java.text.SimpleDateFormat; > import java.util.ArrayList; > import java.util.Date; >@@ -31,8 +32,10 @@ > import java.util.Map; > import java.util.StringTokenizer; > >+import org.eclipse.core.runtime.FileLocator; > import org.eclipse.core.runtime.IPath; > import org.eclipse.core.runtime.Path; >+import org.eclipse.core.runtime.Platform; > import org.eclipse.jdt.core.JavaCore; > import org.eclipse.jdt.core.ToolFactory; > import org.eclipse.jdt.core.compiler.batch.BatchCompiler; >@@ -2754,4 +2757,16 @@ > printJavacResultsSummary(); > } > } >+ /** >+ * Returns the OS path to the directory that contains this plugin. >+ */ >+ protected String getCompilerTestsPluginDirectoryPath() { >+ try { >+ URL platformURL = Platform.getBundle("org.eclipse.jdt.core.tests.compiler").getEntry("/"); >+ return new File(FileLocator.toFileURL(platformURL).getFile()).getAbsolutePath(); >+ } catch (IOException e) { >+ e.printStackTrace(); >+ } >+ return null; >+ } > } >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AmbiguousMethodTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AmbiguousMethodTest.java >index d247111..0c6446f 100644 >--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AmbiguousMethodTest.java >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AmbiguousMethodTest.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -76,6 +76,7 @@ > } > //https://bugs.eclipse.org/bugs/show_bug.cgi?id=122881 > public void test002() { >+ if (this.complianceLevel < ClassFileConstants.JDK1_7) { > this.runConformTest( > new String[] { > "X.java", >@@ -92,8 +93,31 @@ > " }\n" + > "}" > }, >- "works" >- ); >+ "works"); >+ } else { >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " static interface I1<E1> { void method(E1 o); }\n" + >+ " static interface I2<E2> { void method(E2 o); }\n" + >+ " static interface I3<E3, E4> extends I1<E3>, I2<E4> {}\n" + >+ " static class Class1 implements I3<String, String> {\n" + >+ " public void method(String o) { System.out.println(o); }\n" + >+ " }\n" + >+ " public static void main(String[] args) {\n" + >+ " I3<String, String> i = new Class1();\n" + >+ " i.method(\"works\");\n" + >+ " }\n" + >+ "}" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 4)\n" + >+ " static interface I3<E3, E4> extends I1<E3>, I2<E4> {}\n" + >+ " ^^\n" + >+ "Name clash: The method method(E1) of type X.I1<E1> has the same erasure as method(E2) of type X.I2<E2> but does not override it\n" + >+ "----------\n"); >+ } > } > //https://bugs.eclipse.org/bugs/show_bug.cgi?id=122881 > public void test002a() { >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java >index 36aaf2e..4a8b0fa 100644 >--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,8 +7,10 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >- * Stephan Herrmann - Contribution for bug 295551 >- * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 185682 - Increment/decrement operators mark local variables as read >+ * Stephan Herrmann - Contributions for >+ * bug 295551 - Add option to automatically promote all warnings to error >+ * bug 185682 - Increment/decrement operators mark local variables as read >+ * bug 366003 - CCE in ASTNode.resolveAnnotations(ASTNode.java:639) > *******************************************************************************/ > package org.eclipse.jdt.core.tests.compiler.regression; > >@@ -45,7 +47,7 @@ > // Static initializer to specify tests subset using TESTS_* static variables > // All specified tests which do not belong to the class are skipped... > static { >-// TESTS_NAMES = new String[] { "test293" }; >+// TESTS_NAMES = new String[] { "testBug365437" }; > // TESTS_NUMBERS = new int[] { 297 }; > // TESTS_RANGE = new int[] { 294, -1 }; > } >@@ -9848,4 +9850,671 @@ > true, > customOptions); > } >+// Bug 366003 - CCE in ASTNode.resolveAnnotations(ASTNode.java:639) >+// many syntax errors fixed, does not trigger CCE >+public void testBug366003() { >+ runNegativeTest( >+ new String[] { >+ "snippet/Bug366003.java", >+ "package snippet;\n" + >+ "public class Bug366003 {\n" + >+ " public void foo(@NonNull Object o1) {\n" + >+ " System.out.println(o1.toString()); // OK: o1 cannot be null\n" + >+ " } \n" + >+ " @NonNull Object bar(@Nullable String s1) {\n" + >+ " foo(null); // cannot pass null argument\n" + >+ " @NonNull String s= null; // cannot assign null value\n" + >+ " @NonNull String t= s1; // cannot assign potentially null value\n" + >+ " return null; // cannot return null value\n" + >+ " }\n" + >+ "}\n" + >+ "org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + >+ "" >+ }, >+ "----------\n" + >+ "1. ERROR in snippet\\Bug366003.java (at line 3)\n" + >+ " public void foo(@NonNull Object o1) {\n" + >+ " ^^^^^^^\n" + >+ "NonNull cannot be resolved to a type\n" + >+ "----------\n" + >+ "2. ERROR in snippet\\Bug366003.java (at line 6)\n" + >+ " @NonNull Object bar(@Nullable String s1) {\n" + >+ " ^^^^^^^\n" + >+ "NonNull cannot be resolved to a type\n" + >+ "----------\n" + >+ "3. ERROR in snippet\\Bug366003.java (at line 6)\n" + >+ " @NonNull Object bar(@Nullable String s1) {\n" + >+ " ^^^^^^^^\n" + >+ "Nullable cannot be resolved to a type\n" + >+ "----------\n" + >+ "4. ERROR in snippet\\Bug366003.java (at line 8)\n" + >+ " @NonNull String s= null; // cannot assign null value\n" + >+ " ^^^^^^^\n" + >+ "NonNull cannot be resolved to a type\n" + >+ "----------\n" + >+ "5. ERROR in snippet\\Bug366003.java (at line 9)\n" + >+ " @NonNull String t= s1; // cannot assign potentially null value\n" + >+ " ^^^^^^^\n" + >+ "NonNull cannot be resolved to a type\n" + >+ "----------\n" + >+ "6. ERROR in snippet\\Bug366003.java (at line 12)\n" + >+ " }\n" + >+ " ^\n" + >+ "Syntax error on token \"}\", delete this token\n" + >+ "----------\n" + >+ "7. ERROR in snippet\\Bug366003.java (at line 13)\n" + >+ " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + >+ " ^^^^^^^^^^^^^^^^\n" + >+ "Syntax error on tokens, delete these tokens\n" + >+ "----------\n" + >+ "8. ERROR in snippet\\Bug366003.java (at line 13)\n" + >+ " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + >+ " ^^^^\n" + >+ "Syntax error, insert \"enum Identifier\" to complete EnumHeaderName\n" + >+ "----------\n" + >+ "9. ERROR in snippet\\Bug366003.java (at line 13)\n" + >+ " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + >+ " ^^^^\n" + >+ "Syntax error, insert \"EnumBody\" to complete EnumDeclaration\n" + >+ "----------\n" + >+ "10. ERROR in snippet\\Bug366003.java (at line 13)\n" + >+ " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + >+ " ^^^^\n" + >+ "Syntax error, insert \"}\" to complete ClassBody\n" + >+ "----------\n" + >+ "11. ERROR in snippet\\Bug366003.java (at line 13)\n" + >+ " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Return type for the method is missing\n" + >+ "----------\n" + >+ "12. ERROR in snippet\\Bug366003.java (at line 13)\n" + >+ " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + >+ " ^^^^^^^\n" + >+ "NonNull cannot be resolved to a type\n" + >+ "----------\n" + >+ "13. ERROR in snippet\\Bug366003.java (at line 13)\n" + >+ " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + >+ " ^^^^^^^^\n" + >+ "Nullable cannot be resolved to a type\n" + >+ "----------\n" + >+ "14. ERROR in snippet\\Bug366003.java (at line 13)\n" + >+ " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + >+ " ^\n" + >+ "Syntax error, insert \";\" to complete ConstructorDeclaration\n" + >+ "----------\n"); >+} >+// Bug 366003 - CCE in ASTNode.resolveAnnotations(ASTNode.java:639) >+// code is garbage, triggers CCE >+public void testBug366003b() { >+ runNegativeTest( >+ new String[] { >+ "snippet/Bug366003.java", >+ "package snippet;\n" + >+ "public class Bug366003 {\n" + >+ " public void foo(@Blah Object o1) { \n" + >+ "System.out.println(o1.toString()); // OK: o1 cannot be null } \n" + >+ "@Blah Object bar(@BlahBlah String s1) { foo(null); // cannot pass\n" + >+ "null argument @Blah String s= null; // cannot assign null value \n" + >+ " @Blah String t= s1; // cannot assign potentially null value \n" + >+ "return null; // cannot return null value }\n" + >+ "}\n" + >+ "\n" + >+ "org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + >+ "" >+ }, >+ "----------\n" + >+ "1. ERROR in snippet\\Bug366003.java (at line 3)\n" + >+ " public void foo(@Blah Object o1) { \n" + >+ " ^^^^\n" + >+ "Blah cannot be resolved to a type\n" + >+ "----------\n" + >+ "2. ERROR in snippet\\Bug366003.java (at line 4)\n" + >+ " System.out.println(o1.toString()); // OK: o1 cannot be null } \n" + >+ " ^\n" + >+ "Syntax error, insert \"}\" to complete MethodBody\n" + >+ "----------\n" + >+ "3. ERROR in snippet\\Bug366003.java (at line 5)\n" + >+ " @Blah Object bar(@BlahBlah String s1) { foo(null); // cannot pass\n" + >+ " ^^^^\n" + >+ "Blah cannot be resolved to a type\n" + >+ "----------\n" + >+ "4. ERROR in snippet\\Bug366003.java (at line 5)\n" + >+ " @Blah Object bar(@BlahBlah String s1) { foo(null); // cannot pass\n" + >+ " ^^^^^^^^\n" + >+ "BlahBlah cannot be resolved to a type\n" + >+ "----------\n" + >+ "5. ERROR in snippet\\Bug366003.java (at line 6)\n" + >+ " null argument @Blah String s= null; // cannot assign null value \n" + >+ " ^^^^\n" + >+ "Syntax error on token \"null\", @ expected\n" + >+ "----------\n" + >+ "6. ERROR in snippet\\Bug366003.java (at line 11)\n" + >+ " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + >+ " ^^^^^^^^^^^^^^^^\n" + >+ "Syntax error on tokens, delete these tokens\n" + >+ "----------\n" + >+ "7. ERROR in snippet\\Bug366003.java (at line 11)\n" + >+ " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + >+ " ^^^^\n" + >+ "Syntax error, insert \"enum Identifier\" to complete EnumHeaderName\n" + >+ "----------\n" + >+ "8. ERROR in snippet\\Bug366003.java (at line 11)\n" + >+ " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + >+ " ^^^^\n" + >+ "Syntax error, insert \"EnumBody\" to complete EnumDeclaration\n" + >+ "----------\n" + >+ "9. ERROR in snippet\\Bug366003.java (at line 11)\n" + >+ " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + >+ " ^^^^\n" + >+ "Syntax error, insert \"}\" to complete ClassBody\n" + >+ "----------\n" + >+ "10. ERROR in snippet\\Bug366003.java (at line 11)\n" + >+ " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Return type for the method is missing\n" + >+ "----------\n" + >+ "11. ERROR in snippet\\Bug366003.java (at line 11)\n" + >+ " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + >+ " ^^^^^^^\n" + >+ "NonNull cannot be resolved to a type\n" + >+ "----------\n" + >+ "12. ERROR in snippet\\Bug366003.java (at line 11)\n" + >+ " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + >+ " ^^^^^^^^\n" + >+ "Nullable cannot be resolved to a type\n" + >+ "----------\n" + >+ "13. ERROR in snippet\\Bug366003.java (at line 11)\n" + >+ " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + >+ " ^\n" + >+ "Syntax error, insert \";\" to complete ConstructorDeclaration\n" + >+ "----------\n"); >+} >+// Bug 366003 - CCE in ASTNode.resolveAnnotations(ASTNode.java:639) >+// minimal syntax error to trigger CCE >+public void testBug366003c() { >+ runNegativeTest( >+ new String[] { >+ "snippet/Bug366003.java", >+ "package snippet;\n" + >+ "public class Bug366003 {\n" + >+ " void foo(Object o1) {\n" + >+ " }\n" + >+ "org.User(@Bla String a)" >+ }, >+ "----------\n" + >+ "1. ERROR in snippet\\Bug366003.java (at line 5)\n" + >+ " org.User(@Bla String a)\n" + >+ " ^^^\n" + >+ "Syntax error on token \"org\", delete this token\n" + >+ "----------\n" + >+ "2. ERROR in snippet\\Bug366003.java (at line 5)\n" + >+ " org.User(@Bla String a)\n" + >+ " ^^^\n" + >+ "Syntax error, insert \"enum Identifier\" to complete EnumHeaderName\n" + >+ "----------\n" + >+ "3. ERROR in snippet\\Bug366003.java (at line 5)\n" + >+ " org.User(@Bla String a)\n" + >+ " ^^^\n" + >+ "Syntax error, insert \"EnumBody\" to complete EnumDeclaration\n" + >+ "----------\n" + >+ "4. ERROR in snippet\\Bug366003.java (at line 5)\n" + >+ " org.User(@Bla String a)\n" + >+ " ^^^\n" + >+ "Syntax error, insert \"}\" to complete ClassBody\n" + >+ "----------\n" + >+ "5. ERROR in snippet\\Bug366003.java (at line 5)\n" + >+ " org.User(@Bla String a)\n" + >+ " ^^^^^^^^^^^^^^^^^^^\n" + >+ "Return type for the method is missing\n" + >+ "----------\n" + >+ "6. ERROR in snippet\\Bug366003.java (at line 5)\n" + >+ " org.User(@Bla String a)\n" + >+ " ^^^\n" + >+ "Bla cannot be resolved to a type\n" + >+ "----------\n" + >+ "7. ERROR in snippet\\Bug366003.java (at line 5)\n" + >+ " org.User(@Bla String a)\n" + >+ " ^\n" + >+ "Syntax error, insert \";\" to complete ConstructorDeclaration\n" + >+ "----------\n"); >+} >+// unfinished attempt to trigger the same CCE via catch formal parameters >+public void testBug366003d() { >+ runNegativeTest( >+ new String[] { >+ "snippet/Bug366003.java", >+ "package snippet; \n" + >+ "public class Bug366003 {\n" + >+ " void foo() {\n" + >+ " try {\n" + >+ " System.out.println(\"\");\n" + >+ " } catch (Exeption eFirst) {\n" + >+ " e } catch (@Blah Exception eSecond) {\n" + >+ " e }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in snippet\\Bug366003.java (at line 7)\n" + >+ " e } catch (@Blah Exception eSecond) {\n" + >+ " ^\n" + >+ "Syntax error, insert \"AssignmentOperator Expression\" to complete Assignment\n" + >+ "----------\n" + >+ "2. ERROR in snippet\\Bug366003.java (at line 7)\n" + >+ " e } catch (@Blah Exception eSecond) {\n" + >+ " ^\n" + >+ "Syntax error, insert \";\" to complete BlockStatements\n" + >+ "----------\n" + >+ "3. ERROR in snippet\\Bug366003.java (at line 8)\n" + >+ " e }\n" + >+ " ^\n" + >+ "Syntax error, insert \"AssignmentOperator Expression\" to complete Expression\n" + >+ "----------\n" + >+ "4. ERROR in snippet\\Bug366003.java (at line 8)\n" + >+ " e }\n" + >+ " ^\n" + >+ "Syntax error, insert \";\" to complete BlockStatements\n" + >+ "----------\n"); >+} >+public void testBug366003e() { >+ runNegativeTest( >+ new String[] { >+ "snippet/Bug366003.java", >+ "package snippet;\n" + >+ "public class Bug366003 {\n" + >+ " void foo(Object o1){}\n" + >+ " @Blah org.User(@Bla String str){}\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in snippet\\Bug366003.java (at line 4)\n" + >+ " @Blah org.User(@Bla String str){}\n" + >+ " ^^^^\n" + >+ "Blah cannot be resolved to a type\n" + >+ "----------\n" + >+ "2. ERROR in snippet\\Bug366003.java (at line 4)\n" + >+ " @Blah org.User(@Bla String str){}\n" + >+ " ^^^^\n" + >+ "Syntax error on token \"User\", Identifier expected after this token\n" + >+ "----------\n" + >+ "3. ERROR in snippet\\Bug366003.java (at line 4)\n" + >+ " @Blah org.User(@Bla String str){}\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Return type for the method is missing\n" + >+ "----------\n" + >+ "4. ERROR in snippet\\Bug366003.java (at line 4)\n" + >+ " @Blah org.User(@Bla String str){}\n" + >+ " ^^^\n" + >+ "Bla cannot be resolved to a type\n" + >+ "----------\n"); >+} >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=365437 >+public void testBug365437a() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.ERROR); >+ String testFiles [] = new String[] { >+ "p/A.java", >+ "package p;\n" + >+ "import p1.*;\n" + >+ "public class A {\n" + >+ " @p1.PreDestroy\n" + >+ " private void foo1(){}\n" + >+ " @PreDestroy\n" + >+ " private void foo2(){}\n" + >+ " @SuppressWarnings(\"null\")\n" + >+ " @PostConstruct\n" + >+ " private void foo1a(){}\n" + >+ " @PostConstruct\n" + >+ " private void foo2a(){}\n" + >+ " @Deprecated" + >+ " private void foo3(){}" + >+ "}\n", >+ "p1/PreDestroy.java", >+ "package p1;\n" + >+ "public @interface PreDestroy{}", >+ "p1/PostConstruct.java", >+ "package p1;\n" + >+ "public @interface PostConstruct{}" >+ }; >+ String expectedErrorString = >+ "----------\n" + >+ "1. WARNING in p\\A.java (at line 8)\n" + >+ " @SuppressWarnings(\"null\")\n" + >+ " ^^^^^^\n" + >+ "Unnecessary @SuppressWarnings(\"null\")\n" + >+ "----------\n" + >+ "2. ERROR in p\\A.java (at line 13)\n" + >+ " @Deprecated private void foo3(){}}\n" + >+ " ^^^^^^\n" + >+ "The method foo3() from the type A is never used locally\n" + >+ "----------\n"; >+ runNegativeTest( >+ true, >+ testFiles, >+ null, >+ customOptions, >+ expectedErrorString, >+ JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); >+} >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=365437 >+public void testBug365437b() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.ERROR); >+ customOptions.put(CompilerOptions.OPTION_AnnotationBasedNullAnalysis, CompilerOptions.ENABLED); >+ customOptions.put(CompilerOptions.OPTION_NonNullAnnotationName, "p.NonNull"); >+ String testFiles [] = new String[] { >+ "A.java", >+ "import javax.annotation.*;\n" + >+ "public class A {\n" + >+ " @javax.annotation.PreDestroy\n" + >+ " private void foo1(){}\n" + >+ " @PreDestroy\n" + >+ " private void foo2(){}\n" + >+ " @javax.annotation.Resource\n" + >+ " private void foo1a(){}\n" + >+ " @Resource\n" + >+ " @p.NonNull\n" + >+ " private Object foo2a(){ return new Object();}\n" + >+ " @javax.annotation.PostConstruct\n" + >+ " @Deprecated\n" + >+ " private void foo3(){}\n" + >+ " @p.NonNull\n" + >+ " private Object foo3a(){ return new Object();}\n" + >+ "}\n", >+ "p/NonNull.java", >+ "package p;\n" + >+ "import static java.lang.annotation.ElementType.*;\n" + >+ "import java.lang.annotation.*;\n" + >+ "@Target({TYPE, METHOD,PARAMETER,LOCAL_VARIABLE})\n" + >+ "public @interface NonNull {\n" + >+ "}" >+ }; >+ String expectedErrorString = >+ "----------\n" + >+ "1. ERROR in A.java (at line 16)\n" + >+ " private Object foo3a(){ return new Object();}\n" + >+ " ^^^^^^^\n" + >+ "The method foo3a() from the type A is never used locally\n" + >+ "----------\n"; >+ runNegativeTest( >+ true, >+ testFiles, >+ null, >+ customOptions, >+ expectedErrorString, >+ JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); >+} >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=365437 >+// @SafeVarargs >+public void testBug365437c() { >+ if (this.complianceLevel < ClassFileConstants.JDK1_7) return; >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.ERROR); >+ String testFiles [] = new String[] { >+ "p/A.java", >+ "package p;\n" + >+ "import p1.*;\n" + >+ "public class A {\n" + >+ " @p1.PreDestroy\n" + >+ " private void foo1(){}\n" + >+ " @PreDestroy\n" + >+ " private void foo2(){}\n" + >+ " @SuppressWarnings(\"null\")\n" + >+ " @PostConstruct\n" + >+ " private void foo1a(){}\n" + >+ " @PostConstruct\n" + >+ " private void foo2a(){}\n" + >+ " @SafeVarargs" + >+ " private final void foo3(Object... o){}" + >+ "}\n", >+ "p1/PreDestroy.java", >+ "package p1;\n" + >+ "public @interface PreDestroy{}", >+ "p1/PostConstruct.java", >+ "package p1;\n" + >+ "public @interface PostConstruct{}" >+ }; >+ String expectedErrorString = >+ "----------\n" + >+ "1. WARNING in p\\A.java (at line 8)\n" + >+ " @SuppressWarnings(\"null\")\n" + >+ " ^^^^^^\n" + >+ "Unnecessary @SuppressWarnings(\"null\")\n" + >+ "----------\n" + >+ "2. ERROR in p\\A.java (at line 13)\n" + >+ " @SafeVarargs private final void foo3(Object... o){}}\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "The method foo3(Object...) from the type A is never used locally\n" + >+ "----------\n"; >+ runNegativeTest( >+ true, >+ testFiles, >+ null, >+ customOptions, >+ expectedErrorString, >+ JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); >+} >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=365437 >+// unused constructor >+public void testBug365437d() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.ERROR); >+ customOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.ERROR); >+ customOptions.put(CompilerOptions.OPTION_AnnotationBasedNullAnalysis, CompilerOptions.ENABLED); >+ customOptions.put(CompilerOptions.OPTION_NonNullAnnotationName, "p.NonNull"); >+ this.runNegativeTest( >+ true, >+ new String[] { >+ "Example.java", >+ "class Example {\n" + >+ " @p.Annot\n" + >+ " private Example() {\n" + >+ " }\n" + >+ " public Example(int i) {\n" + >+ " }\n" + >+ "}\n" + >+ "class E1 {\n" + >+ " @Deprecated\n" + >+ " private E1() {}\n" + >+ " public E1(long l) {}\n" + >+ "}\n" + >+ "class E2 {\n" + >+ " @SuppressWarnings(\"null\")\n" + >+ " private E2() {}\n" + >+ " public E2(long l) {}\n" + >+ "}\n" + >+ "class E3 {\n" + >+ " @p.NonNull\n" + >+ " private E3() {}\n" + >+ " public E3(long l) {}\n" + >+ "}\n" + >+ "class E4 {\n" + >+ " @Deprecated\n" + >+ " @p.Annot\n" + >+ " private E4() {}\n" + >+ " public E4(long l) {}\n" + >+ "}\n", >+ "p/NonNull.java", >+ "package p;\n" + >+ "import static java.lang.annotation.ElementType.*;\n" + >+ "import java.lang.annotation.*;\n" + >+ "@Target({TYPE, METHOD,PARAMETER,CONSTRUCTOR})\n" + >+ "public @interface NonNull {\n" + >+ "}", >+ "p/Annot.java", >+ "package p;\n" + >+ "import static java.lang.annotation.ElementType.*;\n" + >+ "import java.lang.annotation.*;\n" + >+ "@Target({TYPE, METHOD,PARAMETER,LOCAL_VARIABLE, CONSTRUCTOR})\n" + >+ "public @interface Annot {\n" + >+ "}" >+ }, >+ null, customOptions, >+ "----------\n" + >+ "1. ERROR in Example.java (at line 10)\n" + >+ " private E1() {}\n" + >+ " ^^^^\n" + >+ "The constructor E1() is never used locally\n" + >+ "----------\n" + >+ "2. WARNING in Example.java (at line 14)\n" + >+ " @SuppressWarnings(\"null\")\n" + >+ " ^^^^^^\n" + >+ "Unnecessary @SuppressWarnings(\"null\")\n" + >+ "----------\n" + >+ "3. ERROR in Example.java (at line 15)\n" + >+ " private E2() {}\n" + >+ " ^^^^\n" + >+ "The constructor E2() is never used locally\n" + >+ "----------\n" + >+ "4. ERROR in Example.java (at line 20)\n" + >+ " private E3() {}\n" + >+ " ^^^^\n" + >+ "The constructor E3() is never used locally\n" + >+ "----------\n", >+ JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); >+} >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=365437 >+// unused field >+public void testBug365437e() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.ERROR); >+ customOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.ERROR); >+ customOptions.put(CompilerOptions.OPTION_AnnotationBasedNullAnalysis, CompilerOptions.ENABLED); >+ customOptions.put(CompilerOptions.OPTION_NonNullAnnotationName, "p.NonNull"); >+ this.runNegativeTest( >+ true, >+ new String[] { >+ "Example.java", >+ "class Example {\n" + >+ " @p.Annot\n" + >+ " private int Ex;\n" + >+ "}\n" + >+ "class E1 {\n" + >+ " @Deprecated\n" + >+ " private int E1;\n" + >+ "}\n" + >+ "class E2 {\n" + >+ " @SuppressWarnings(\"null\")\n" + >+ " private int E2;\n" + >+ "}\n" + >+ "class E3 {\n" + >+ " @p.NonNull\n" + >+ " private int E3;\n" + >+ "}\n" + >+ "class E4 {\n" + >+ " @Deprecated\n" + >+ " @p.Annot\n" + >+ " private int E4;\n" + >+ "}\n", >+ "p/NonNull.java", >+ "package p;\n" + >+ "import static java.lang.annotation.ElementType.*;\n" + >+ "import java.lang.annotation.*;\n" + >+ "@Target({TYPE, METHOD,PARAMETER,LOCAL_VARIABLE, FIELD})\n" + >+ "public @interface NonNull {\n" + >+ "}", >+ "p/Annot.java", >+ "package p;\n" + >+ "import static java.lang.annotation.ElementType.*;\n" + >+ "import java.lang.annotation.*;\n" + >+ "@Target({TYPE, METHOD,PARAMETER,LOCAL_VARIABLE, FIELD})\n" + >+ "public @interface Annot {\n" + >+ "}" >+ }, >+ null, customOptions, >+ "----------\n" + >+ "1. ERROR in Example.java (at line 7)\n" + >+ " private int E1;\n" + >+ " ^^\n" + >+ "The value of the field E1.E1 is not used\n" + >+ "----------\n" + >+ "2. WARNING in Example.java (at line 10)\n" + >+ " @SuppressWarnings(\"null\")\n" + >+ " ^^^^^^\n" + >+ "Unnecessary @SuppressWarnings(\"null\")\n" + >+ "----------\n" + >+ "3. ERROR in Example.java (at line 11)\n" + >+ " private int E2;\n" + >+ " ^^\n" + >+ "The value of the field E2.E2 is not used\n" + >+ "----------\n" + >+ "4. ERROR in Example.java (at line 15)\n" + >+ " private int E3;\n" + >+ " ^^\n" + >+ "The value of the field E3.E3 is not used\n" + >+ "----------\n", >+ JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); >+} >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=365437 >+// unused type >+public void testBug365437f() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.ERROR); >+ customOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.ERROR); >+ customOptions.put(CompilerOptions.OPTION_AnnotationBasedNullAnalysis, CompilerOptions.ENABLED); >+ customOptions.put(CompilerOptions.OPTION_NonNullAnnotationName, "p.NonNull"); >+ this.runNegativeTest( >+ true, >+ new String[] { >+ "Example.java", >+ "class Example {\n" + >+ " @p.Annot\n" + >+ " private class Ex{}\n" + >+ "}\n" + >+ "class E1 {\n" + >+ " @Deprecated\n" + >+ " private class E11{}\n" + >+ "}\n" + >+ "class E2 {\n" + >+ " @SuppressWarnings(\"null\")\n" + >+ " private class E22{}\n" + >+ "}\n" + >+ "class E3 {\n" + >+ " @p.NonNull\n" + >+ " private class E33{}\n" + >+ "}\n" + >+ "class E4 {\n" + >+ " @Deprecated\n" + >+ " @p.Annot\n" + >+ " private class E44{}\n" + >+ "}\n", >+ "p/NonNull.java", >+ "package p;\n" + >+ "import static java.lang.annotation.ElementType.*;\n" + >+ "import java.lang.annotation.*;\n" + >+ "@Target({TYPE, METHOD,PARAMETER,LOCAL_VARIABLE})\n" + >+ "public @interface NonNull {\n" + >+ "}", >+ "p/Annot.java", >+ "package p;\n" + >+ "import static java.lang.annotation.ElementType.*;\n" + >+ "import java.lang.annotation.*;\n" + >+ "@Target({TYPE, METHOD,PARAMETER,LOCAL_VARIABLE, CONSTRUCTOR})\n" + >+ "public @interface Annot {\n" + >+ "}" >+ }, >+ null, customOptions, >+ "----------\n" + >+ "1. ERROR in Example.java (at line 7)\n" + >+ " private class E11{}\n" + >+ " ^^^\n" + >+ "The type E1.E11 is never used locally\n" + >+ "----------\n" + >+ "2. WARNING in Example.java (at line 10)\n" + >+ " @SuppressWarnings(\"null\")\n" + >+ " ^^^^^^\n" + >+ "Unnecessary @SuppressWarnings(\"null\")\n" + >+ "----------\n" + >+ "3. ERROR in Example.java (at line 11)\n" + >+ " private class E22{}\n" + >+ " ^^^\n" + >+ "The type E2.E22 is never used locally\n" + >+ "----------\n" + >+ "4. ERROR in Example.java (at line 15)\n" + >+ " private class E33{}\n" + >+ " ^^^\n" + >+ "The type E3.E33 is never used locally\n" + >+ "----------\n", >+ JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); >+} > } >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AssignmentTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AssignmentTest.java >index 42ccda4..8a0b1d2 100644 >--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AssignmentTest.java >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AssignmentTest.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2005, 2010 IBM Corporation and others. >+ * Copyright (c) 2005, 2011 IBM Corporation 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 >@@ -13,6 +13,7 @@ > > import java.util.Map; > >+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; > import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; > > import junit.framework.Test; >@@ -1221,7 +1222,7 @@ > "1. ERROR in p\\X.java (at line 4)\n" + > " public static String s;\n" + > " ^\n" + >- "The field s cannot be declared static; static fields can only be declared in static or top level types\n" + >+ "The field s cannot be declared static in a non-static inner type, unless initialized with a constant expression\n" + > "----------\n" + > "2. ERROR in p\\X.java (at line 6)\n" + > " X.XX.s = s; }\n" + >@@ -1929,6 +1930,88 @@ > options > ); > } >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=362279 >+public void test068() { >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " Integer f = 'a'; // Field declaration.\n" + >+ " public Integer main() {\n" + >+ " Integer i = 'a'; // local declaration with initialization.\n" + >+ " i = 'a'; // assignment\n" + >+ " Integer [] ia = new Integer [] { 'a' }; // array initializer.\n" + >+ " return 'a'; // return statement.\n" + >+ " switch (i) {\n" + >+ " case 'a' : // case statement\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ this.complianceLevel < ClassFileConstants.JDK1_5 ? >+ "----------\n" + >+ "1. ERROR in X.java (at line 2)\n" + >+ " Integer f = \'a\'; // Field declaration.\n" + >+ " ^^^\n" + >+ "Type mismatch: cannot convert from char to Integer\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 4)\n" + >+ " Integer i = \'a\'; // local declaration with initialization.\n" + >+ " ^^^\n" + >+ "Type mismatch: cannot convert from char to Integer\n" + >+ "----------\n" + >+ "3. ERROR in X.java (at line 5)\n" + >+ " i = \'a\'; // assignment\n" + >+ " ^^^\n" + >+ "Type mismatch: cannot convert from char to Integer\n" + >+ "----------\n" + >+ "4. ERROR in X.java (at line 6)\n" + >+ " Integer [] ia = new Integer [] { \'a\' }; // array initializer.\n" + >+ " ^^^\n" + >+ "Type mismatch: cannot convert from char to Integer\n" + >+ "----------\n" + >+ "5. ERROR in X.java (at line 7)\n" + >+ " return \'a\'; // return statement.\n" + >+ " ^^^\n" + >+ "Type mismatch: cannot convert from char to Integer\n" + >+ "----------\n" + >+ "6. ERROR in X.java (at line 8)\n" + >+ " switch (i) {\n" + >+ " ^\n" + >+ "Cannot switch on a value of type Integer. Only convertible int values or enum variables are permitted\n" + >+ "----------\n" : >+ "----------\n" + >+ "1. ERROR in X.java (at line 2)\n" + >+ " Integer f = \'a\'; // Field declaration.\n" + >+ " ^^^\n" + >+ "Type mismatch: cannot convert from char to Integer\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 4)\n" + >+ " Integer i = \'a\'; // local declaration with initialization.\n" + >+ " ^^^\n" + >+ "Type mismatch: cannot convert from char to Integer\n" + >+ "----------\n" + >+ "3. ERROR in X.java (at line 5)\n" + >+ " i = \'a\'; // assignment\n" + >+ " ^^^\n" + >+ "Type mismatch: cannot convert from char to Integer\n" + >+ "----------\n" + >+ "4. ERROR in X.java (at line 6)\n" + >+ " Integer [] ia = new Integer [] { \'a\' }; // array initializer.\n" + >+ " ^^^\n" + >+ "Type mismatch: cannot convert from char to Integer\n" + >+ "----------\n" + >+ "5. ERROR in X.java (at line 7)\n" + >+ " return \'a\'; // return statement.\n" + >+ " ^^^\n" + >+ "Type mismatch: cannot convert from char to Integer\n" + >+ "----------\n" + >+ "6. ERROR in X.java (at line 9)\n" + >+ " case \'a\' : // case statement\n" + >+ " ^^^\n" + >+ "Type mismatch: cannot convert from char to Integer\n" + >+ "----------\n"); >+} > public static Class testClass() { > return AssignmentTest.class; > } >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AutoBoxingTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AutoBoxingTest.java >index 52c9f6d..b12d264 100644 >--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AutoBoxingTest.java >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AutoBoxingTest.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2005, 2009 IBM Corporation and others. >+ * Copyright (c) 2005, 2011 IBM Corporation 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 >@@ -2911,7 +2911,7 @@ > > // https://bugs.eclipse.org/bugs/show_bug.cgi?id=85491 > public void test101() { >- this.runConformTest( >+ this.runNegativeTest( > new String[] { > "X.java", > "public class X {\n" + >@@ -2924,8 +2924,22 @@ > " }\n" + > "}\n", > }, >- "222" >- ); >+ "----------\n" + >+ "1. ERROR in X.java (at line 5)\n" + >+ " new X().foo(1);\n" + >+ " ^^^\n" + >+ "The method foo(Object[]) is ambiguous for the type X\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 6)\n" + >+ " new X().foo(new Integer(1));\n" + >+ " ^^^\n" + >+ "The method foo(Object[]) is ambiguous for the type X\n" + >+ "----------\n" + >+ "3. ERROR in X.java (at line 7)\n" + >+ " new X().foo(1, new Integer(1));\n" + >+ " ^^^\n" + >+ "The method foo(Object[]) is ambiguous for the type X\n" + >+ "----------\n"); > this.runNegativeTest( > new String[] { > "X.java", >@@ -4859,7 +4873,7 @@ > } > //https://bugs.eclipse.org/bugs/show_bug.cgi?id=231709 > public void test165() { >- this.runConformTest( >+ this.runNegativeTest( > new String[] { > "X.java", > "public class X {\n" + >@@ -4892,7 +4906,67 @@ > " } \n" + > "}\n", > }, >- ""); >+ "----------\n" + >+ "1. WARNING in X.java (at line 3)\n" + >+ " Integer i1 = 10 ;\n" + >+ " ^^\n" + >+ "The expression of type int is boxed into Integer\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 5)\n" + >+ " i1 = s;\n" + >+ " ^\n" + >+ "Type mismatch: cannot convert from short to Integer\n" + >+ "----------\n" + >+ "3. WARNING in X.java (at line 6)\n" + >+ " switch (i1)\n" + >+ " ^^\n" + >+ "The expression of type Integer is unboxed into int\n" + >+ "----------\n" + >+ "4. ERROR in X.java (at line 8)\n" + >+ " case s:\n" + >+ " ^\n" + >+ "Type mismatch: cannot convert from short to Integer\n" + >+ "----------\n" + >+ "5. WARNING in X.java (at line 12)\n" + >+ " Integer i2 = 10 ;\n" + >+ " ^^\n" + >+ "The expression of type int is boxed into Integer\n" + >+ "----------\n" + >+ "6. ERROR in X.java (at line 14)\n" + >+ " i2 = b;\n" + >+ " ^\n" + >+ "Type mismatch: cannot convert from byte to Integer\n" + >+ "----------\n" + >+ "7. WARNING in X.java (at line 15)\n" + >+ " switch (i2)\n" + >+ " ^^\n" + >+ "The expression of type Integer is unboxed into int\n" + >+ "----------\n" + >+ "8. ERROR in X.java (at line 17)\n" + >+ " case b:\n" + >+ " ^\n" + >+ "Type mismatch: cannot convert from byte to Integer\n" + >+ "----------\n" + >+ "9. WARNING in X.java (at line 21)\n" + >+ " Integer i3 = 10 ;\n" + >+ " ^^\n" + >+ "The expression of type int is boxed into Integer\n" + >+ "----------\n" + >+ "10. ERROR in X.java (at line 23)\n" + >+ " i3 = c;\n" + >+ " ^\n" + >+ "Type mismatch: cannot convert from char to Integer\n" + >+ "----------\n" + >+ "11. WARNING in X.java (at line 24)\n" + >+ " switch (i3)\n" + >+ " ^^\n" + >+ "The expression of type Integer is unboxed into int\n" + >+ "----------\n" + >+ "12. ERROR in X.java (at line 26)\n" + >+ " case c:\n" + >+ " ^\n" + >+ "Type mismatch: cannot convert from char to Integer\n" + >+ "----------\n"); > } > > //https://bugs.eclipse.org/bugs/show_bug.cgi?id=231709 - variation >@@ -4947,35 +5021,35 @@ > " ^\n" + > "Type mismatch: cannot convert from char to Integer\n" + > "----------\n" + >- "4. WARNING in X.java (at line 11)\n" + >+ "4. ERROR in X.java (at line 11)\n" + > " Integer is = s;\n" + > " ^\n" + >- "The expression of type short is boxed into Integer\n" + >+ "Type mismatch: cannot convert from short to Integer\n" + > "----------\n" + >- "5. WARNING in X.java (at line 12)\n" + >+ "5. ERROR in X.java (at line 12)\n" + > " Integer ib = b;\n" + > " ^\n" + >- "The expression of type byte is boxed into Integer\n" + >+ "Type mismatch: cannot convert from byte to Integer\n" + > "----------\n" + >- "6. WARNING in X.java (at line 13)\n" + >+ "6. ERROR in X.java (at line 13)\n" + > " Integer ic = c; \n" + > " ^\n" + >- "The expression of type char is boxed into Integer\n" + >+ "Type mismatch: cannot convert from char to Integer\n" + > "----------\n" + >- "7. WARNING in X.java (at line 16)\n" + >+ "7. ERROR in X.java (at line 16)\n" + > " Integer is = (short)0;\n" + > " ^^^^^^^^\n" + >- "The expression of type short is boxed into Integer\n" + >+ "Type mismatch: cannot convert from short to Integer\n" + > "----------\n" + >- "8. WARNING in X.java (at line 17)\n" + >+ "8. ERROR in X.java (at line 17)\n" + > " Integer ib = (byte)0;\n" + > " ^^^^^^^\n" + >- "The expression of type byte is boxed into Integer\n" + >+ "Type mismatch: cannot convert from byte to Integer\n" + > "----------\n" + >- "9. WARNING in X.java (at line 18)\n" + >+ "9. ERROR in X.java (at line 18)\n" + > " Integer ic = (char)0; \n" + > " ^^^^^^^\n" + >- "The expression of type char is boxed into Integer\n" + >+ "Type mismatch: cannot convert from char to Integer\n" + > "----------\n" + > "10. WARNING in X.java (at line 21)\n" + > " Short si = 0;\n" + >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java >index eb6e3f7..af0d0b0 100644 >--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -8,9 +8,15 @@ > * Contributors: > * IBM Corporation - initial API and implementation > * Benjamin Muskalla - Contribution for bug 239066 >- * Stephan Herrmann - Contribution for bug 236385 >- * Stephan Herrmann - Contribution for bug 295551 >- * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 185682 - Increment/decrement operators mark local variables as read >+ * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for >+ * bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used >+ * bug 295551 - Add option to automatically promote all warnings to errors >+ * bug 185682 - Increment/decrement operators mark local variables as read >+ * bug 349326 - [1.7] new warning for missing try-with-resources >+ * bug 359721 - [options] add command line option for new warning token "resource" >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 365208 - [compiler][batch] command line options for annotation based null analysis >+ * bug 370639 - [compiler][resource] restore the default for resource leak warnings > *******************************************************************************/ > package org.eclipse.jdt.core.tests.compiler.regression; > >@@ -47,8 +53,33 @@ > static final String JRE_HOME_DIR = Util.getJREDirectory(); > private static final Main MAIN = new Main(null/*outWriter*/, null/*errWriter*/, false/*systemExit*/, null/*options*/, null/*progress*/); > >+ private static final String NONNULL_BY_DEFAULT_ANNOTATION_CONTENT = "package org.eclipse.jdt.annotation;\n" + >+ "import static java.lang.annotation.ElementType.*;\n" + >+ "import java.lang.annotation.*;\n" + >+ "@Documented\n" + >+ "@Retention(RetentionPolicy.CLASS)\n" + >+ "@Target({ PACKAGE, TYPE, METHOD, CONSTRUCTOR })\n" + >+ "public @interface NonNullByDefault{\n" + >+ "}"; >+ private static final String NULLABLE_ANNOTATION_CONTENT = "package org.eclipse.jdt.annotation;\n" + >+ "import static java.lang.annotation.ElementType.*;\n" + >+ "import java.lang.annotation.*;\n" + >+ "@Documented\n" + >+ "@Retention(RetentionPolicy.CLASS)\n" + >+ "@Target({ METHOD, PARAMETER })\n" + >+ "public @interface Nullable{\n" + >+ "}\n"; >+ private static final String NONNULL_ANNOTATION_CONTENT = "package org.eclipse.jdt.annotation;\n" + >+ "import static java.lang.annotation.ElementType.*;\n" + >+ "import java.lang.annotation.*;\n" + >+ "@Documented\n" + >+ "@Retention(RetentionPolicy.CLASS)\n" + >+ "@Target({ METHOD, PARAMETER })\n" + >+ "public @interface NonNull{\n" + >+ "}\n"; >+ > static { >-// TESTS_NAMES = new String[] { "test295_warn_options" }; >+// TESTS_NAMES = new String[] { "test31" }; > // TESTS_NUMBERS = new int[] { 306 }; > // TESTS_RANGE = new int[] { 298, -1 }; > } >@@ -1546,6 +1577,9 @@ > " -deprecation + deprecation outside deprecated code (equivalent to\n" + > " -warn:+deprecation)\n" + > " -nowarn -warn:none disable all warnings\n" + >+ " -nowarn:[<directories separated by " + File.pathSeparator+ ">]\n" + >+ " specify directories from which optional problems should\n" + >+ " be ignored\n" + > " -?:warn -help:warn display advanced warning options\n" + > " \n" + > " Error options:\n" + >@@ -1610,6 +1644,8 @@ > " -enableJavadoc consider references in javadoc\n" + > " -Xemacs used to enable emacs-style output in the console.\n" + > " It does not affect the xml log output\n" + >+ " -nonNullByDefault for annotation based null analysis assume nonnull\n" + >+ " as the global default\n" + > " \n" + > " -? -help print this help message\n" + > " -v -version print compiler version\n" + >@@ -1656,14 +1692,18 @@ > " Warning options:\n" + > " -deprecation + deprecation outside deprecated code\n" + > " -nowarn -warn:none disable all warnings\n" + >+ " -nowarn:[<directories separated by " + File.pathSeparator+ ">]\n" + >+ " specify directories from which optional problems should\n" + >+ " be ignored\n" + > " -warn:<warnings separated by ,> enable exactly the listed warnings\n" + > " -warn:+<warnings separated by ,> enable additional warnings\n" + > " -warn:-<warnings separated by ,> disable specific warnings\n" + >+ " all enable all warnings\n" + > " allDeadCode dead code including trivial if(DEBUG) check\n" + > " allDeprecation deprecation including inside deprecated code\n" + > " allJavadoc invalid or missing javadoc\n" + > " allOver-ann all missing @Override annotations\n" + >- " all-static-method all method can be declared as static warnings\n" + >+ " all-static-method all method can be declared as static warnings\n" + > " assertIdentifier + ''assert'' used as identifier\n" + > " boxing autoboxing conversion\n" + > " charConcat + char[] in String concat\n" + >@@ -1697,11 +1737,15 @@ > " nls string literal lacking non-nls tag //$NON-NLS-<n>$\n" + > " noEffectAssign + assignment without effect\n" + > " null potential missing or redundant null check\n" + >+ " nullAnnot(<annot. names separated by |>) + annotation based null analysis,\n" + >+ " nullable|nonnull|nonnullbydefault annotation types\n" + >+ " optionally specified using fully qualified names\n" + > " nullDereference + missing null check\n" + > " over-ann missing @Override annotation (superclass)\n" + > " paramAssign assignment to a parameter\n" + > " pkgDefaultMethod + attempt to override package-default method\n" + > " raw + usage of raw type\n" + >+ " resource + (pot.) unsafe usage of resource of type Closeable\n" + > " semicolon unnecessary semicolon, empty statement\n" + > " serial + missing serialVersionUID\n" + > " specialParamHiding constructor or setter parameter hiding a field\n" + >@@ -1716,7 +1760,7 @@ > " syntheticAccess synthetic access for innerclass\n" + > " tasks(<tags separated by |>) tasks identified by tags inside comments\n" + > " typeHiding + type parameter hiding another type\n" + >- " unavoidableGenericProblems + ignore unavoidable type safety problems\n" + >+ " unavoidableGenericProblems + ignore unavoidable type safety problems\n" + > " due to raw APIs\n" + > " unchecked + unchecked type operation\n" + > " unnecessaryElse unnecessary else clause\n" + >@@ -1734,7 +1778,7 @@ > " unusedTypeArgs + unused type arguments for method and constructor\n" + > " uselessTypeCheck unnecessary cast/instanceof operation\n" + > " varargsCast + varargs argument need explicit cast\n" + >- " warningToken + unsupported or unnecessary @SuppressWarnings\n" + >+ " warningToken + unsupported or unnecessary @SuppressWarnings\n" + > "\n"; > String expandedExpectedOutput = > MessageFormat.format(expectedOutput, new String[] { >@@ -1794,6 +1838,11 @@ > " <argument value=\"---OUTPUT_DIR_PLACEHOLDER---\"/>\n" + > " </command_line>\n" + > " <options>\n" + >+ " <option key=\"org.eclipse.jdt.core.compiler.annotation.nonnull\" value=\"org.eclipse.jdt.annotation.NonNull\"/>\n" + >+ " <option key=\"org.eclipse.jdt.core.compiler.annotation.nonnullbydefault\" value=\"org.eclipse.jdt.annotation.NonNullByDefault\"/>\n" + >+ " <option key=\"org.eclipse.jdt.core.compiler.annotation.nonnullisdefault\" value=\"disabled\"/>\n" + >+ " <option key=\"org.eclipse.jdt.core.compiler.annotation.nullable\" value=\"org.eclipse.jdt.annotation.Nullable\"/>\n" + >+ " <option key=\"org.eclipse.jdt.core.compiler.annotation.nullanalysis\" value=\"disabled\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode\" value=\"disabled\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.codegen.targetPlatform\" value=\"1.5\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.codegen.unusedLocal\" value=\"optimize out\"/>\n" + >@@ -1803,7 +1852,7 @@ > " <option key=\"org.eclipse.jdt.core.compiler.debug.sourceFile\" value=\"generate\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.doc.comment.support\" value=\"disabled\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.generateClassFiles\" value=\"enabled\"/>\n" + >- " <option key=\"org.eclipse.jdt.core.compiler.maxProblemPerUnit\" value=\"100\"/>\n" + >+ " <option key=\"org.eclipse.jdt.core.compiler.maxProblemPerUnit\" value=\"100\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.annotationSuperInterface\" value=\"warning\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.assertIdentifier\" value=\"warning\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.autoboxing\" value=\"ignore\"/>\n" + >@@ -1816,6 +1865,7 @@ > " <option key=\"org.eclipse.jdt.core.compiler.problem.discouragedReference\" value=\"warning\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.emptyStatement\" value=\"ignore\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.enumIdentifier\" value=\"warning\"/>\n" + >+ " <option key=\"org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable\" value=\"ignore\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.fallthroughCase\" value=\"ignore\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.fatalOptionalError\" value=\"disabled\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.fieldHiding\" value=\"ignore\"/>\n" + >@@ -1852,12 +1902,17 @@ > " <option key=\"org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion\" value=\"warning\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral\" value=\"ignore\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.nullReference\" value=\"warning\"/>\n" + >+ " <option key=\"org.eclipse.jdt.core.compiler.problem.nullSpecInsufficientInfo\" value=\"warning\"/>\n" + >+ " <option key=\"org.eclipse.jdt.core.compiler.problem.nullSpecViolation\" value=\"error\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.overridingMethodWithoutSuperInvocation\" value=\"ignore\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod\" value=\"warning\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.parameterAssignment\" value=\"ignore\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment\" value=\"ignore\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.potentialNullReference\" value=\"ignore\"/>\n" + >- " <option key=\"org.eclipse.jdt.core.compiler.problem.rawTypeReference\" value=\"warning\"/>\n" + >+ " <option key=\"org.eclipse.jdt.core.compiler.problem.potentialNullSpecViolation\" value=\"error\"/>\n" + >+ " <option key=\"org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable\" value=\"ignore\"/>\n" + >+ " <option key=\"org.eclipse.jdt.core.compiler.problem.rawTypeReference\" value=\"warning\"/>\n" + >+ " <option key=\"org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation\" value=\"warning\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.redundantNullCheck\" value=\"ignore\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments\" value=\"ignore\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.redundantSuperinterface\" value=\"ignore\"/>\n" + >@@ -1870,8 +1925,9 @@ > " <option key=\"org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation\" value=\"ignore\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.tasks\" value=\"warning\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.typeParameterHiding\" value=\"warning\"/>\n" + >- " <option key=\"org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems\" value=\"enabled\"/>\n" + >+ " <option key=\"org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems\" value=\"enabled\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation\" value=\"warning\"/>\n" + >+ " <option key=\"org.eclipse.jdt.core.compiler.problem.unclosedCloseable\" value=\"warning\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock\" value=\"ignore\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.unhandledWarningToken\" value=\"warning\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.problem.unnecessaryElse\" value=\"ignore\"/>\n" + >@@ -1897,7 +1953,7 @@ > " <option key=\"org.eclipse.jdt.core.compiler.source\" value=\"1.5\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.taskCaseSensitive\" value=\"enabled\"/>\n" + > " <option key=\"org.eclipse.jdt.core.compiler.taskPriorities\" value=\"\"/>\n" + >- " <option key=\"org.eclipse.jdt.core.compiler.taskTags\" value=\"\"/>\n" + >+ " <option key=\"org.eclipse.jdt.core.compiler.taskTags\" value=\"\"/>\n" + > " </options>\n" + > " <classpaths>NORMALIZED SECTION</classpaths>\n" + > " <sources>\n" + >@@ -6872,7 +6928,7 @@ > "3. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 13)\n" + > " } catch (E1 e1) {\n" + > " ^^\n" + >- "Unreachable catch block for E1. Only more specific exceptions are thrown and handled by previous catch block(s).\n" + >+ "Unreachable catch block for E1. Only more specific exceptions are thrown and they are handled by previous catch block(s).\n" + > "----------\n" + > "3 problems (3 warnings)", > true); >@@ -6940,7 +6996,7 @@ > "4. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 13)\n" + > " } catch (E1 e1) {\n" + > " ^^\n" + >- "Unreachable catch block for E1. Only more specific exceptions are thrown and handled by previous catch block(s).\n" + >+ "Unreachable catch block for E1. Only more specific exceptions are thrown and they are handled by previous catch block(s).\n" + > "----------\n" + > "4 problems (4 warnings)", > true); >@@ -7075,7 +7131,7 @@ > "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 13)\n" + > " } catch (E1 e1) {\n" + > " ^^\n" + >- "Unreachable catch block for E1. Only more specific exceptions are thrown and handled by previous catch block(s).\n" + >+ "Unreachable catch block for E1. Only more specific exceptions are thrown and they are handled by previous catch block(s).\n" + > "----------\n" + > "1 problem (1 warning)", > true); >@@ -7175,7 +7231,7 @@ > "3. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 13)\n" + > " } catch (E1 e1) {\n" + > " ^^\n" + >- "Unreachable catch block for E1. Only more specific exceptions are thrown and handled by previous catch block(s).\n" + >+ "Unreachable catch block for E1. Only more specific exceptions are thrown and they are handled by previous catch block(s).\n" + > "----------\n" + > "3 problems (3 warnings)", > true); >@@ -7230,7 +7286,7 @@ > "3. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 13)\n" + > " } catch (E1 e1) {\n" + > " ^^\n" + >- "Unreachable catch block for E1. Only more specific exceptions are thrown and handled by previous catch block(s).\n" + >+ "Unreachable catch block for E1. Only more specific exceptions are thrown and they are handled by previous catch block(s).\n" + > "----------\n" + > "3 problems (3 warnings)", > true); >@@ -7340,7 +7396,7 @@ > "3. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 13)\n" + > " } catch (E1 e1) {\n" + > " ^^\n" + >- "Unreachable catch block for E1. Only more specific exceptions are thrown and handled by previous catch block(s).\n" + >+ "Unreachable catch block for E1. Only more specific exceptions are thrown and they are handled by previous catch block(s).\n" + > "----------\n" + > "3 problems (3 warnings)", > true); >@@ -8508,48 +8564,6 @@ > "The value of the parameter i is not used\n" + > "----------\n" + > "1 problem (1 warning)", >- true); >-} >-// https://bugs.eclipse.org/bugs/show_bug.cgi?id=210518 >-// variant >-public void test214_warn_options() { >- // same source as 153, skip default checks >- this.runNegativeTest( >- new String[] { >- "X.java", >- "public class X {\n" + >- " public static void foo() {\n" + >- " String s = null;\n" + >- " s.toString();\n" + >- " String u;\n" + >- " }\n" + >- "}", >- }, >- "\"" + OUTPUT_DIR + File.separator + "X.java\"" >- + " -warn:null,-unused -proc:none -d \"" + OUTPUT_DIR + "\"", >- "", >- "usage of \'-\' for \'-unused\' is illegal there\n", >- true); >-} >-// https://bugs.eclipse.org/bugs/show_bug.cgi?id=210518 >-// variant >-public void test215_warn_options() { >- // same source as 153, skip default checks >- this.runNegativeTest( >- new String[] { >- "X.java", >- "public class X {\n" + >- " public static void foo() {\n" + >- " String s = null;\n" + >- " s.toString();\n" + >- " String u;\n" + >- " }\n" + >- "}", >- }, >- "\"" + OUTPUT_DIR + File.separator + "X.java\"" >- + " -warn:null,+unused -proc:none -d \"" + OUTPUT_DIR + "\"", >- "", >- "usage of \'+\' for \'+unused\' is illegal there\n", > true); > } > // https://bugs.eclipse.org/bugs/show_bug.cgi?id=211588 >@@ -11398,24 +11412,6 @@ > true); > } > //https://bugs.eclipse.org/bugs/show_bug.cgi?id=280784 >-public void test295(){ >- this.runNegativeTest( >- new String[] { >- "src/X.java", >- "public class X {\n" + >- "}", >- }, >- "\"" + OUTPUT_DIR + File.separator + "src/X.java\"" >- + " -cp \"" + LIB_DIR + "\"" >- + " -sourcepath \"" + OUTPUT_DIR + File.separator + "src\"" >- + " -1.5 -g -preserveAllLocals" >- + " -proceedOnError -referenceInfo -err:raw,+discouraged" >- + " -d \"" + OUTPUT_DIR + File.separator + "bin\" ", >- "", >- "usage of \'+\' for \'+discouraged\' is illegal there\n", >- true); >-} >-//https://bugs.eclipse.org/bugs/show_bug.cgi?id=280784 > public void test296(){ > this.runNegativeTest( > new String[] { >@@ -12295,4 +12291,760 @@ > "3 problems (1 error, 2 warnings)", > true); > } >+//-warn option - regression tests >+public void test0308_warn_options() { >+ // check the option introduced in bug 359721 >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.FileReader;\n" + >+ "public class X {\n" + >+ " void foo() throws java.io.IOException {\n" + >+ " FileReader r = new FileReader(\"f1\");\n" + >+ " char[] cs = new char[1024];\n" + >+ " r.read(cs);\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "\"" + OUTPUT_DIR + File.separator + "X.java\"" >+ + " -warn:-resource -1.7 -d \"" + OUTPUT_DIR + "\"", >+ "", >+ "", >+ true); >+} >+//-warn option - regression tests >+public void test0309_warn_options() { >+ // check the option introduced in bug 359721 >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.FileReader;\n" + >+ "public class X {\n" + >+ " void foo(boolean b) throws java.io.IOException {\n" + >+ " FileReader r = new FileReader(\"f1\");\n" + >+ " char[] cs = new char[1024];\n" + >+ " r.read(cs);\n" + >+ " if (b) r.close();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "\"" + OUTPUT_DIR + File.separator + "X.java\"" >+ + " -warn:+resource -1.7 -d \"" + OUTPUT_DIR + "\"", >+ "", >+ "----------\n" + >+ "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 4)\n" + >+ " FileReader r = new FileReader(\"f1\");\n" + >+ " ^\n" + >+ "Potential resource leak: \'r\' may not be closed\n" + >+ "----------\n" + >+ "1 problem (1 warning)", >+ true); >+} >+ >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=366829 >+// -warn option - regression test to check option syncOverride >+// Warning when when a class overrides a synchronized method without synchronizing it >+public void test310_warn_options() { >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "class X { synchronized void foo() {} }\n" + >+ "class Y extends X { @Override void foo() { } }" >+ }, >+ "\"" + OUTPUT_DIR + File.separator + "X.java\"" >+ + " -sourcepath \"" + OUTPUT_DIR + "\"" >+ + " -warn:syncOverride -1.5 -proc:none -d \"" + OUTPUT_DIR + "\"", >+ "", >+ "----------\n" + >+ "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 2)\n" + >+ " class Y extends X { @Override void foo() { } }\n" + >+ " ^^^^^\n" + >+ "The method Y.foo() is overriding a synchronized method without being synchronized\n" + >+ "----------\n" + >+ "1 problem (1 warning)", >+ true); >+} >+ >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=366829 >+// -warn option - regression test to check option syncOverride >+// Warning when when a class overrides a synchronized method without synchronizing it >+public void test310b_warn_options() { >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " void bar() { new X() { @Override void foo() {} }; }\n"+ >+ " synchronized void foo() { }\n"+ >+ "}" >+ }, >+ "\"" + OUTPUT_DIR + File.separator + "X.java\"" >+ + " -sourcepath \"" + OUTPUT_DIR + "\"" >+ + " -warn:syncOverride -1.5 -proc:none -d \"" + OUTPUT_DIR + "\"", >+ "", >+ "----------\n" + >+ "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 2)\n" + >+ " void bar() { new X() { @Override void foo() {} }; }\n"+ >+ " ^^^^^\n" + >+ "The method new X(){}.foo() is overriding a synchronized method without being synchronized\n" + >+ "----------\n" + >+ "1 problem (1 warning)", >+ true); >+} >+ >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=325342 >+// -warn option - regression tests to check option nullAnnot (with args) >+// Null warnings because of annotations - custom annotation types used - challenging various kinds of diagnostics >+public void test312_warn_options() { >+ this.runConformTest( >+ new String[] { >+ "p/X.java", >+ "package p;\n" + >+ "import static java.lang.annotation.ElementType.*;\n" + >+ "import java.lang.annotation.*;\n" + >+ "@SuppressWarnings(\"unused\")\n" + >+ "public class X {\n" + >+ " public void test() { Object o = null; o.toString();}\n" + >+ " @NonNull Object foo(@Nullable Object o, @NonNull Object o2) {\n" + >+ " if (o.toString() == \"\"){ return null;}\n" + >+ " if (o2 == null) {}\n" + >+ " goo(null).toString();\n" + >+ " Object local = null;\n" + >+ " o.toString();\n" + >+ " return null;\n" + >+ " }\n" + >+ " @Nullable Object goo(@NonNull Object o2) {\n" + >+ " return new Object();\n" + >+ " }\n" + >+ " @NonNullByDefault Object hoo(Object o2) {\n" + >+ " if (o2 == null){}\n" + >+ " if (o2 == null){\n" + >+ " return null;\n" + >+ " }\n" + >+ " return new Object();\n" + >+ " }\n" + >+ "}\n" + >+ "@Documented\n" + >+ "@Retention(RetentionPolicy.CLASS)\n" + >+ "@Target({ METHOD, PARAMETER })\n" + >+ "@interface NonNull{\n" + >+ "}\n" + >+ "@Documented\n" + >+ "@Retention(RetentionPolicy.CLASS)\n" + >+ "@Target({ METHOD, PARAMETER })\n" + >+ "@interface Nullable{\n" + >+ "}\n" + >+ "@Documented\n" + >+ "@Retention(RetentionPolicy.CLASS)\n" + >+ "@Target({ PACKAGE, TYPE, METHOD, CONSTRUCTOR })\n" + >+ "@interface NonNullByDefault{\n" + >+ "}" >+ }, >+ "\"" + OUTPUT_DIR + File.separator + "p" + File.separator + "X.java\"" >+// + " -sourcepath \"" + OUTPUT_DIR + "\"" >+ + " -1.5" >+ + " -warn:+nullAnnot(p.Nullable|p.NonNull|p.NonNullByDefault) -warn:+null -proc:none -d \"" + OUTPUT_DIR + "\"", >+ "", >+ "----------\n" + >+ "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 6)\n" + >+ " public void test() { Object o = null; o.toString();}\n" + >+ " ^\n" + >+ "Null pointer access: The variable o can only be null at this location\n" + >+ "----------\n" + >+ "2. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 8)\n" + >+ " if (o.toString() == \"\"){ return null;}\n" + >+ " ^\n" + >+ "Potential null pointer access: The variable o may be null at this location\n" + >+ "----------\n" + >+ "3. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 8)\n" + >+ " if (o.toString() == \"\"){ return null;}\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + >+ "----------\n" + >+ "4. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 9)\n" + >+ " if (o2 == null) {}\n" + >+ " ^^\n" + >+ "Null comparison always yields false: The variable o2 cannot be null at this location\n" + >+ "----------\n" + >+ "5. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 10)\n" + >+ " goo(null).toString();\n" + >+ " ^^^^^^^^^\n" + >+ "Potential null pointer access: The method goo(Object) may return null\n" + >+ "----------\n" + >+ "6. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 10)\n" + >+ " goo(null).toString();\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + >+ "----------\n" + >+ "7. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 13)\n" + >+ " return null;\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + >+ "----------\n" + >+ "8. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 19)\n" + >+ " if (o2 == null){}\n" + >+ " ^^\n" + >+ "Null comparison always yields false: The variable o2 cannot be null at this location\n" + >+ "----------\n" + >+ "9. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 20)\n" + >+ " if (o2 == null){\n" + >+ " ^^\n" + >+ "Null comparison always yields false: The variable o2 cannot be null at this location\n" + >+ "----------\n" + >+ "9 problems (9 warnings)", >+ true); >+} >+ >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=325342 >+// -warn option - regression tests to check option nullAnnot (no args) >+// Null warnings because of annotations, null spec violations >+public void test313_warn_options() { >+ this.runConformTest( >+ new String[] { >+ "p/X.java", >+ "package p;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " @NonNull Object foo(@Nullable Object o, @NonNull Object o2) {\n" + >+ " return this;\n" + >+ " }\n" + >+ "}\n" + >+ "class Y extends X {\n" + >+ " @Nullable Object foo(Object o, Object o2) { return null; }\n" + >+ "}\n", >+ "org/eclipse/jdt/annotation/NonNull.java", >+ NONNULL_ANNOTATION_CONTENT, >+ "org/eclipse/jdt/annotation/Nullable.java", >+ NULLABLE_ANNOTATION_CONTENT, >+ "org/eclipse/jdt/annotation/NonNullByDefault.java", >+ NONNULL_BY_DEFAULT_ANNOTATION_CONTENT >+ }, >+ "\"" + OUTPUT_DIR + File.separator + "p" + File.separator + "X.java\"" >+ + " -sourcepath \"" + OUTPUT_DIR + "\"" >+ + " -1.5" >+ + " -warn:+nullAnnot -warn:-null -proc:none -d \"" + OUTPUT_DIR + "\"", >+ "", >+ "----------\n" + >+ "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 9)\n" + >+ " @Nullable Object foo(Object o, Object o2) { return null; }\n" + >+ " ^^^^^^^^^^^^^^^^\n" + >+ "The return type is incompatible with the @NonNull return from X.foo(Object, Object)\n" + >+ "----------\n" + >+ "2. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 9)\n" + >+ " @Nullable Object foo(Object o, Object o2) { return null; }\n" + >+ " ^^^^^^\n" + >+ "Missing nullable annotation: inherited method from X declares this parameter as @Nullable\n" + >+ "----------\n" + >+ "3. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 9)\n" + >+ " @Nullable Object foo(Object o, Object o2) { return null; }\n" + >+ " ^^^^^^\n" + >+ "Missing non-null annotation: inherited method from X declares this parameter as @NonNull\n" + >+ "----------\n" + >+ "3 problems (3 warnings)", >+ true); >+} >+ >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=325342 >+// -err option - regression tests to check option nullAnnot >+// Null warnings because of annotations, null spec violations configured as errors >+public void test314_warn_options() { >+ this.runNegativeTest( >+ new String[] { >+ "p/X.java", >+ "package p;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " @NonNull Object foo(@Nullable Object o, @NonNull Object o2) {\n" + >+ " return this;\n" + >+ " }\n" + >+ "}\n" + >+ "class Y extends X {\n" + >+ " @Nullable Object foo(Object o, Object o2) { return null; }\n" + >+ "}\n", >+ "org/eclipse/jdt/annotation/NonNull.java", >+ NONNULL_ANNOTATION_CONTENT, >+ "org/eclipse/jdt/annotation/Nullable.java", >+ NULLABLE_ANNOTATION_CONTENT, >+ "org/eclipse/jdt/annotation/NonNullByDefault.java", >+ NONNULL_BY_DEFAULT_ANNOTATION_CONTENT >+ }, >+ "\"" + OUTPUT_DIR + File.separator + "p" + File.separator + "X.java\"" >+ + " -sourcepath \"" + OUTPUT_DIR + "\"" >+ + " -1.5" >+ + " -err:+nullAnnot -warn:-null -proc:none -d \"" + OUTPUT_DIR + "\"", >+ "", >+ "----------\n" + >+ "1. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 9)\n" + >+ " @Nullable Object foo(Object o, Object o2) { return null; }\n" + >+ " ^^^^^^^^^^^^^^^^\n" + >+ "The return type is incompatible with the @NonNull return from X.foo(Object, Object)\n" + >+ "----------\n" + >+ "2. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 9)\n" + >+ " @Nullable Object foo(Object o, Object o2) { return null; }\n" + >+ " ^^^^^^\n" + >+ "Missing nullable annotation: inherited method from X declares this parameter as @Nullable\n" + >+ "----------\n" + >+ "3. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 9)\n" + >+ " @Nullable Object foo(Object o, Object o2) { return null; }\n" + >+ " ^^^^^^\n" + >+ "Missing non-null annotation: inherited method from X declares this parameter as @NonNull\n" + >+ "----------\n" + >+ "3 problems (3 errors)", >+ true); >+} >+ >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=325342 >+// -warn option - regression tests to check option nullAnnot >+// Null warnings because of annotations, global nonNullByDefault >+// DISABLED due to dysfunctional global default after Bug 366063 - Compiler should not add synthetic @NonNull annotations >+public void _test315_warn_options() { >+ this.runConformTest( >+ new String[] { >+ "p/X.java", >+ "package p;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@SuppressWarnings(\"unused\")\n" + >+ "public class X {\n" + >+ " Object foo(@Nullable Object o, Object o2) {\n" + >+ " if (o.toString() == \"\"){ return null;}\n" + >+ " if (o2 == null) {}\n" + >+ " goo(null).toString();\n" + >+ " return null;\n" + >+ " }\n" + >+ " @Nullable Object goo(Object o2) {\n" + >+ " return new Object();\n" + >+ " }\n" + >+ " @NonNullByDefault Object hoo(Object o2) {\n" + // redundant >+ " if (o2 == null)\n" + >+ " return null;\n" + >+ " return this;\n" + >+ " }\n" + >+ "}\n", >+ "org/eclipse/jdt/annotation/NonNull.java", >+ NONNULL_ANNOTATION_CONTENT, >+ "org/eclipse/jdt/annotation/Nullable.java", >+ NULLABLE_ANNOTATION_CONTENT, >+ "org/eclipse/jdt/annotation/NonNullByDefault.java", >+ NONNULL_BY_DEFAULT_ANNOTATION_CONTENT >+ }, >+ "\"" + OUTPUT_DIR + File.separator + "p" + File.separator + "X.java\"" >+ + " -sourcepath \"" + OUTPUT_DIR + "\"" >+ + " -1.5" >+ + " -warn:+nullAnnot -warn:+null -nonNullByDefault -proc:none -d \"" + OUTPUT_DIR + "\"", >+ "", >+ "----------\n" + >+ "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 6)\n" + >+ " if (o.toString() == \"\"){ return null;}\n" + >+ " ^\n" + >+ "Potential null pointer access: The variable o may be null at this location\n" + >+ "----------\n" + >+ "2. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 6)\n" + >+ " if (o.toString() == \"\"){ return null;}\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + >+ "----------\n" + >+ "3. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 7)\n" + >+ " if (o2 == null) {}\n" + >+ " ^^\n" + >+ "Null comparison always yields false: The variable o2 cannot be null at this location\n" + >+ "----------\n" + >+ "4. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 8)\n" + >+ " goo(null).toString();\n" + >+ " ^^^^^^^^^\n" + >+ "Potential null pointer access: The method goo(Object) may return null\n" + >+ "----------\n" + >+ "5. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 8)\n" + >+ " goo(null).toString();\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + >+ "----------\n" + >+ "6. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 9)\n" + >+ " return null;\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + >+ "----------\n" + >+ "7. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 14)\n" + >+ " @NonNullByDefault Object hoo(Object o2) {\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with the global default\n" + >+ "----------\n" + >+ "8. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 15)\n" + >+ " if (o2 == null)\n" + >+ " ^^\n" + >+ "Null comparison always yields false: The variable o2 cannot be null at this location\n" + >+ "----------\n" + >+ "8 problems (8 warnings)", >+ true); >+} >+ >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=325342 >+// -warn option - regression tests to check option nullAnnot >+// option syntax error >+public void test316_warn_options() { >+ this.runNegativeTest( >+ new String[] { >+ "p/X.java", >+ "package p;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@SuppressWarnings(\"unused\")\n" + >+ "public class X {}\n", >+ "org/eclipse/jdt/annotation/NonNull.java", >+ NONNULL_ANNOTATION_CONTENT, >+ "org/eclipse/jdt/annotation/Nullable.java", >+ NULLABLE_ANNOTATION_CONTENT, >+ "org/eclipse/jdt/annotation/NonNullByDefault.java", >+ NONNULL_BY_DEFAULT_ANNOTATION_CONTENT >+ }, >+ "\"" + OUTPUT_DIR + File.separator + "p" + File.separator + "X.java\"" >+ + " -sourcepath \"" + OUTPUT_DIR + "\"" >+ + " -1.5" >+ + " -warn:+nullAnnot(foo|bar) -warn:+null -nonNullByDefault -proc:none -d \"" + OUTPUT_DIR + "\"", >+ "", >+ "Token nullAnnot(foo|bar) is not in the expected format \"nullAnnot(<non null annotation name> | <nullable annotation name> | <non-null by default annotation name>)\"\n", >+ true); >+} >+ >+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=220928 >+//-nowarn option - regression tests >+//default >+public void test317_nowarn_options() { >+ this.runConformTest( >+ new String[] { >+ "src/X.java", >+ "public class X {\n" + >+ " /**\n" + >+ " @param\n" + >+ " */\n" + >+ " public void foo() {\n" + >+ " }\n" + >+ "}", >+ }, >+ "\"" + OUTPUT_DIR + File.separator + "src/X.java\"" >+ + " -warn:javadoc -nowarn:[\"" + >+ OUTPUT_DIR + File.separator + "src" + >+ "\"] -proc:none -d \"" + OUTPUT_DIR + "\"", >+ "", >+ "", >+ true); >+} >+ >+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=220928 >+//-nowarn option - regression tests >+//two different source folders ignore only from one >+public void test318_nowarn_options() { >+ this.runConformTest( >+ new String[] { >+ "src/X.java", >+ "public class X {\n" + >+ " /**\n" + >+ " @param\n" + >+ " */\n" + >+ " public void foo() {\n" + >+ " }\n" + >+ "}", >+ "src2/Y.java", >+ "public class Y {\n" + >+ " /**\n" + >+ " @param\n" + >+ " */\n" + >+ " public void foo() {\n" + >+ " }\n" + >+ "}" >+ }, >+ "\"" + OUTPUT_DIR + File.separator + "src/X.java\"" + >+ " \"" + OUTPUT_DIR + File.separator + "src2/Y.java\"" + >+ " -warn:javadoc -nowarn:[" + >+ "\"" + OUTPUT_DIR + File.separator + "src" >+ + "\"] -proc:none -d \"" + OUTPUT_DIR + "\"", >+ "", >+ "----------\n" + >+ "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/src2/Y.java (at line 3)\n" + >+ " @param\n" + >+ " ^^^^^\n" + >+ "Javadoc: Missing parameter name\n" + >+ "----------\n" + >+ "1 problem (1 warning)", >+ true); >+} >+ >+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=220928 >+//-nowarn option - regression tests >+//two different source folders ignore from both >+public void test319_nowarn_options() { >+ this.runConformTest( >+ new String[] { >+ "src1/X.java", >+ "public class X {\n" + >+ " /**\n" + >+ " @param\n" + >+ " */\n" + >+ " public void foo() {\n" + >+ " }\n" + >+ "}", >+ "src2/Y.java", >+ "public class Y {\n" + >+ " /**\n" + >+ " @param\n" + >+ " */\n" + >+ " public void foo() {\n" + >+ " }\n" + >+ "}" >+ }, >+ "\"" + OUTPUT_DIR + File.separator + "src1/X.java\"" + >+ " \"" + OUTPUT_DIR + File.separator + "src2/Y.java\"" + >+ " -warn:javadoc -nowarn:[" + >+ "\"" + OUTPUT_DIR + File.separator + "src1\"" + File.pathSeparator + >+ "\"" + OUTPUT_DIR + File.separator + >+ "src2\"] -proc:none -d \"" + OUTPUT_DIR + "\"", >+ "", >+ "", >+ true); >+} >+ >+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=220928 >+//-nowarn option - regression tests >+//two different source folders ignore from both using multiple -nowarn >+public void test320_nowarn_options() { >+ this.runConformTest( >+ new String[] { >+ "src1/X.java", >+ "public class X {\n" + >+ " /**\n" + >+ " @param\n" + >+ " */\n" + >+ " public void foo() {\n" + >+ " }\n" + >+ "}", >+ "src2/Y.java", >+ "public class Y {\n" + >+ " /**\n" + >+ " @param\n" + >+ " */\n" + >+ " public void foo() {\n" + >+ " }\n" + >+ "}" >+ }, >+ "\"" + OUTPUT_DIR + File.separator + "src1/X.java\"" + >+ " \"" + OUTPUT_DIR + File.separator + "src2/Y.java\"" + >+ " -warn:javadoc -nowarn:[" + >+ "\"" + OUTPUT_DIR + File.separator + "src1\"] -nowarn:[" + >+ "\"" + OUTPUT_DIR + File.separator + "src2\"] " + >+ "-proc:none -d \"" + OUTPUT_DIR + "\"", >+ "", >+ "", >+ true); >+} >+ >+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=220928 >+//-nowarn option - regression tests >+//option syntax error -nowarn: >+public void test321_nowarn_options() { >+ this.runNegativeTest( >+ new String[] { >+ "src/X.java", >+ "public class X {\n" + >+ " /**\n" + >+ " @param\n" + >+ " */\n" + >+ " public void foo() {\n" + >+ " }\n" + >+ "}", >+ }, >+ "\"" + OUTPUT_DIR + File.separator + "src/X.java\"" >+ + " -warn:javadoc -nowarn: -proc:none -d \"" + OUTPUT_DIR + "\"", >+ "", >+ "invalid syntax for nowarn option: -nowarn:\n", >+ true); >+} >+ >+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=220928 >+//-nowarn option - regression tests >+//option syntax error -nowarn:[ >+public void test322_nowarn_options() { >+ this.runNegativeTest( >+ new String[] { >+ "src/X.java", >+ "public class X {\n" + >+ " /**\n" + >+ " @param\n" + >+ " */\n" + >+ " public void foo() {\n" + >+ " }\n" + >+ "}", >+ }, >+ "\"" + OUTPUT_DIR + File.separator + "src/X.java\"" >+ + " -warn:javadoc -nowarn:[ -proc:none -d \"" + OUTPUT_DIR + "\"", >+ "", >+ "invalid syntax for nowarn option: -nowarn:[\n", >+ true); >+} >+ >+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=220928 >+//-nowarn option - regression tests >+//option syntax error -nowarn:[src >+public void test323_nowarn_options() { >+ this.runNegativeTest( >+ new String[] { >+ "src/X.java", >+ "public class X {\n" + >+ " /**\n" + >+ " @param\n" + >+ " */\n" + >+ " public void foo() {\n" + >+ " }\n" + >+ "}", >+ }, >+ "\"" + OUTPUT_DIR + File.separator + "src/X.java\"" >+ + " -warn:javadoc -nowarn:[src -proc:none -d \"" + OUTPUT_DIR + "\"", >+ "", >+ "invalid syntax for nowarn option: -nowarn:[src\n", >+ true); >+} >+ >+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=220928 >+//-nowarn option - regression tests >+//option syntax error -nowarn:src] >+public void test324_nowarn_options() { >+ this.runNegativeTest( >+ new String[] { >+ "src/X.java", >+ "public class X {\n" + >+ " /**\n" + >+ " @param\n" + >+ " */\n" + >+ " public void foo() {\n" + >+ " }\n" + >+ "}", >+ }, >+ "\"" + OUTPUT_DIR + File.separator + "src/X.java\"" >+ + " -warn:javadoc -nowarn:src] -proc:none -d \"" + OUTPUT_DIR + "\"", >+ "", >+ "invalid syntax for nowarn option: -nowarn:src]\n", >+ true); >+} >+ >+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=220928 >+//-nowarn option - regression tests >+//option syntax error -nowarn[src] >+public void test325_nowarn_options() { >+ this.runNegativeTest( >+ new String[] { >+ "src/X.java", >+ "public class X {\n" + >+ " /**\n" + >+ " @param\n" + >+ " */\n" + >+ " public void foo() {\n" + >+ " }\n" + >+ "}", >+ }, >+ "\"" + OUTPUT_DIR + File.separator + "src/X.java\"" >+ + " -warn:javadoc -nowarn[src] -proc:none -d \"" + OUTPUT_DIR + "\"", >+ "", >+ "invalid syntax for nowarn option: -nowarn[src]\n", >+ true); >+} >+ >+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=220928 >+//-nowarn option - regression tests >+//option syntax error -nowarn:[src1]src2 >+public void test326_nowarn_options() { >+ this.runNegativeTest( >+ new String[] { >+ "src/X.java", >+ "public class X {\n" + >+ " /**\n" + >+ " @param\n" + >+ " */\n" + >+ " public void foo() {\n" + >+ " }\n" + >+ "}", >+ }, >+ "\"" + OUTPUT_DIR + File.separator + "src/X.java\"" >+ + " -warn:javadoc -nowarn:[src1]src2 -proc:none -d \"" + OUTPUT_DIR + "\"", >+ "", >+ "invalid syntax for nowarn option: -nowarn:[src1]src2\n", >+ true); >+} >+ >+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=220928 >+//-nowarn option - regression tests >+//option syntax error -nowarn:[] >+public void test327_nowarn_options() { >+ this.runNegativeTest( >+ new String[] { >+ "src/X.java", >+ "public class X {\n" + >+ " /**\n" + >+ " @param\n" + >+ " */\n" + >+ " public void foo() {\n" + >+ " }\n" + >+ "}", >+ }, >+ "\"" + OUTPUT_DIR + File.separator + "src/X.java\"" >+ + " -warn:javadoc -nowarn:[] -proc:none -d \"" + OUTPUT_DIR + "\"", >+ "", >+ "invalid syntax for nowarn option: -nowarn:[]\n", >+ true); >+} >+ >+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=220928 >+//-nowarn option - regression tests >+//non-optional errors cannot be ignored >+public void test328_nowarn_options() { >+ this.runNegativeTest( >+ new String[] { >+ "src/X.java", >+ "public class X {\n" + >+ " /**\n" + >+ " @param\n" + >+ " */\n" + >+ " public void foo() {\n" + >+ " a++;\n" + >+ " }\n" + >+ "}", >+ }, >+ "\"" + OUTPUT_DIR + File.separator + "src/X.java\"" >+ + " -warn:javadoc -nowarn:[" + >+ "\"" + OUTPUT_DIR + File.separator + "src]\" -proc:none -d \"" + OUTPUT_DIR + "\"", >+ "", >+ "----------\n" + >+ "1. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/src/X.java (at line 6)\n" + >+ " a++;\n" + >+ " ^\n" + >+ "a cannot be resolved to a variable\n" + >+ "----------\n" + >+ "1 problem (1 error)", >+ true); >+} >+ >+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=220928 >+//-nowarn option - regression tests >+//task tags cannot be ignored >+public void test329_nowarn_options() { >+ this.runConformTest( >+ new String[] { >+ "src/X.java", >+ "public class X {\n" + >+ " /**\n" + >+ " @param\n" + >+ " */\n" + >+ " public void foo() {\n" + >+ " // TODO nothing\n" + >+ " }\n" + >+ "}", >+ }, >+ "\"" + OUTPUT_DIR + File.separator + "src/X.java\"" >+ + " -warn:javadoc,tasks(TODO) -nowarn:[" + >+ "\"" + OUTPUT_DIR + File.separator + "src]\" -proc:none -d \"" + OUTPUT_DIR + "\"", >+ "", >+ "----------\n" + >+ "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/src/X.java (at line 6)\n" + >+ " // TODO nothing\n" + >+ " ^^^^^^^^^^^^\n" + >+ "TODO nothing\n" + >+ "----------\n" + >+ "1 problem (1 warning)", >+ true); >+} > } >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BootstrapMethodAttributeTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BootstrapMethodAttributeTest.java >new file mode 100644 >index 0000000..15d6b01 >--- /dev/null >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BootstrapMethodAttributeTest.java >@@ -0,0 +1,74 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 IBM Corporation 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.core.tests.compiler.regression; >+ >+import java.io.File; >+ >+import junit.framework.Test; >+ >+import org.eclipse.jdt.core.ToolFactory; >+import org.eclipse.jdt.core.tests.util.Util; >+import org.eclipse.jdt.core.util.ClassFileBytesDisassembler; >+ >+public class BootstrapMethodAttributeTest extends AbstractRegressionTest { >+ public BootstrapMethodAttributeTest(String name) { >+ super(name); >+ } >+ >+ public static Class testClass() { >+ return BootstrapMethodAttributeTest.class; >+ } >+ >+ // Use this static initializer to specify subset for tests >+ // All specified tests which does not belong to the class are skipped... >+ static { >+// TESTS_PREFIX = "testBug95521"; >+// TESTS_NAMES = new String[] { "testBug359495" }; >+// TESTS_NUMBERS = new int[] { 53 }; >+// TESTS_RANGE = new int[] { 23 -1,}; >+ } >+ public static Test suite() { >+ return buildMinimalComplianceTestSuite(testClass(), F_1_7); >+ } >+ public void test001() throws Exception { >+ >+ ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler(); >+ String path = this.getCompilerTestsPluginDirectoryPath() + File.separator + "workspace" + File.separator + "TestBootstrapMethodAtt.class"; >+ byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(new File(path)); >+ String actualOutput = >+ disassembler.disassemble( >+ classFileBytes, >+ "\n", >+ ClassFileBytesDisassembler.DETAILED); >+ >+ String expectedOutput = >+ "// (version 1.2 : 46.0, no super bit)\n" + >+ "public class test.G {\n" + >+ " \n" + >+ " // Method descriptor #2 ()V\n" + >+ " // Stack: 0, Locals: 0\n" + >+ " public static void call();\n" + >+ " 0 invokedynamic 0 dyn() : void [18]\n" + >+ " 5 return\n" + >+ "\n" + >+ "Bootstrap methods:\n" + >+ " 0 : # 17 arguments: {#1}\n" + >+ "}"; >+ >+ int index = actualOutput.indexOf(expectedOutput); >+ if (index == -1 || expectedOutput.length() == 0) { >+ System.out.println(Util.displayString(actualOutput, 2)); >+ } >+ if (index == -1) { >+ assertEquals("Wrong contents", expectedOutput, actualOutput); >+ } >+ } >+} >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CastTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CastTest.java >index cef41ac..c7c9427 100644 >--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CastTest.java >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CastTest.java >@@ -2374,6 +2374,54 @@ > "SUCCESS" > ); > } >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=359284 >+// Verify that checkcast is emitted for a cast expression. >+public void test061b() throws Exception { >+ String source = >+ "public class X {\n" + >+ "public X() {\n" + >+ " Object[] x = (Object[])null;\n" + >+ "}\n" + >+ "}\n"; >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ source >+ }, >+ "" >+ ); >+ String expectedOutput = >+ "public class X {\n" + >+ " \n" + >+ " // Method descriptor #6 ()V\n" + >+ " // Stack: 1, Locals: 2\n" + >+ " public X();\n" + >+ " 0 aload_0 [this]\n" + >+ " 1 invokespecial java.lang.Object() [8]\n" + >+ " 4 aconst_null\n" + >+ " 5 checkcast java.lang.Object[] [10]\n" + >+ " 8 astore_1 [x]\n" + >+ " 9 return\n" + >+ " Line numbers:\n" + >+ " [pc: 0, line: 2]\n" + >+ " [pc: 4, line: 3]\n" + >+ " [pc: 9, line: 4]\n" + >+ " Local variable table:\n" + >+ " [pc: 0, pc: 10] local: this index: 0 type: X\n" + >+ " [pc: 9, pc: 10] local: x index: 1 type: java.lang.Object[]\n" + >+ "}"; >+ File f = new File(OUTPUT_DIR + File.separator + "X.class"); >+ byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(f); >+ ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler(); >+ String result = disassembler.disassemble(classFileBytes, "\n", ClassFileBytesDisassembler.DETAILED); >+ int index = result.indexOf(expectedOutput); >+ if (index == -1 || expectedOutput.length() == 0) { >+ System.out.println(Util.displayString(result, 3)); >+ } >+ if (index == -1) { >+ assertEquals("Wrong contents", expectedOutput, result); >+ } >+} > public static Class testClass() { > return CastTest.class; > } >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java >index da7a3b6..b0803a2 100644 >--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2006, 2011 IBM Corporation and others. >+ * Copyright (c) 2006, 2012 IBM Corporation 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 >@@ -8,7 +8,11 @@ > * Contributors: > * IBM Corporation - initial API and implementation > * Benjamin Muskalla - Contribution for bug 239066 >- * Stephan Herrmann - Contribution for bug 236385 >+ * Stephan Herrmann - Contributions for >+ * bug 236385: [compiler] Warn for potential programming problem if an object is created but not used >+ * bug 349326 - [1.7] new warning for missing try-with-resources >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 365662 - [compiler][null] warn on contradictory and redundant null annotations > *******************************************************************************/ > package org.eclipse.jdt.core.tests.compiler.regression; > >@@ -378,6 +382,7 @@ > expectedProblemAttributes.put("CannotDefineStaticInitializerInLocalType", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); > expectedProblemAttributes.put("CannotExtendEnum", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); > expectedProblemAttributes.put("CannotHideAnInstanceMethodWithAStaticMethod", new ProblemAttributes(CategorizedProblem.CAT_MEMBER)); >+ expectedProblemAttributes.put("CannotImplementIncompatibleNullness", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); > expectedProblemAttributes.put("CannotImportPackage", new ProblemAttributes(CategorizedProblem.CAT_IMPORT)); > expectedProblemAttributes.put("CannotInferElidedTypes", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); > expectedProblemAttributes.put("CannotInvokeSuperConstructorInEnum", new ProblemAttributes(CategorizedProblem.CAT_MEMBER)); >@@ -393,6 +398,7 @@ > expectedProblemAttributes.put("CodeCannotBeReached", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); > expectedProblemAttributes.put("CodeSnippetMissingClass", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); > expectedProblemAttributes.put("CodeSnippetMissingMethod", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); >+ expectedProblemAttributes.put("ContradictoryNullAnnotations", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); > expectedProblemAttributes.put("ComparingIdentical", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); > expectedProblemAttributes.put("ConflictingImport", new ProblemAttributes(CategorizedProblem.CAT_IMPORT)); > expectedProblemAttributes.put("ConstructorVarargsArgumentNeedCast", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); >@@ -440,6 +446,7 @@ > expectedProblemAttributes.put("ExceptionTypeInternalNameProvided", DEPRECATED); > expectedProblemAttributes.put("ExceptionTypeNotFound", DEPRECATED); > expectedProblemAttributes.put("ExceptionTypeNotVisible", DEPRECATED); >+ expectedProblemAttributes.put("ExplicitlyClosedAutoCloseable", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE)); > expectedProblemAttributes.put("ExpressionShouldBeAVariable", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX)); > expectedProblemAttributes.put("ExternalProblemFixable", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); > expectedProblemAttributes.put("ExternalProblemNotFixable", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); >@@ -467,8 +474,10 @@ > expectedProblemAttributes.put("HierarchyHasProblems", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); > expectedProblemAttributes.put("IllegalAbstractModifierCombinationForMethod", new ProblemAttributes(CategorizedProblem.CAT_MEMBER)); > expectedProblemAttributes.put("IllegalAccessFromTypeVariable", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); >+ expectedProblemAttributes.put("IllegalAnnotationForBaseType", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); > expectedProblemAttributes.put("IllegalCast", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); > expectedProblemAttributes.put("IllegalClassLiteralForTypeVariable", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); >+ expectedProblemAttributes.put("IllegalDefinitionToNonNullParameter", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); > expectedProblemAttributes.put("IllegalDimension", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); > expectedProblemAttributes.put("IllegalEnclosingInstanceSpecification", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); > expectedProblemAttributes.put("IllegalExtendedDimensions", new ProblemAttributes(CategorizedProblem.CAT_MEMBER)); >@@ -503,6 +512,8 @@ > expectedProblemAttributes.put("IllegalPrimitiveOrArrayTypeForEnclosingInstance", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); > expectedProblemAttributes.put("IllegalQualifiedEnumConstantLabel", new ProblemAttributes(CategorizedProblem.CAT_MEMBER)); > expectedProblemAttributes.put("IllegalQualifiedParameterizedTypeAllocation", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); >+ expectedProblemAttributes.put("IllegalReturnNullityRedefinition", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); >+ expectedProblemAttributes.put("IllegalRedefinitionToNonNullParameter", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); > expectedProblemAttributes.put("IllegalStaticModifierForMemberType", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); > expectedProblemAttributes.put("IllegalTypeVariableSuperReference", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); > expectedProblemAttributes.put("IllegalUnderscorePosition", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX)); >@@ -742,6 +753,8 @@ > expectedProblemAttributes.put("PackageCollidesWithType", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); > expectedProblemAttributes.put("PackageIsNotExpectedPackage", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); > expectedProblemAttributes.put("ParameterAssignment", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE)); >+ expectedProblemAttributes.put("ParameterLackingNonNullAnnotation", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); >+ expectedProblemAttributes.put("ParameterLackingNullableAnnotation", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); > expectedProblemAttributes.put("ParameterMismatch", new ProblemAttributes(CategorizedProblem.CAT_MEMBER)); > expectedProblemAttributes.put("ParameterizedConstructorArgumentTypeMismatch", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); > expectedProblemAttributes.put("ParameterizedMethodArgumentTypeMismatch", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); >@@ -765,7 +778,10 @@ > expectedProblemAttributes.put("PolymorphicMethodNotBelow17", new ProblemAttributes(CategorizedProblem.CAT_MEMBER)); > expectedProblemAttributes.put("PossibleAccidentalBooleanAssignment", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); > expectedProblemAttributes.put("PotentialHeapPollutionFromVararg", new ProblemAttributes(CategorizedProblem.CAT_UNCHECKED_RAW)); >+ expectedProblemAttributes.put("PotentiallyUnclosedCloseable", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); >+ expectedProblemAttributes.put("PotentiallyUnclosedCloseableAtExit", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); > expectedProblemAttributes.put("PotentialNullLocalVariableReference", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); >+ expectedProblemAttributes.put("PotentialNullMessageSendReference", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); > expectedProblemAttributes.put("PublicClassMustMatchFileName", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); > expectedProblemAttributes.put("RawMemberTypeCannotBeParameterized", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); > expectedProblemAttributes.put("RawTypeReference", new ProblemAttributes(CategorizedProblem.CAT_UNCHECKED_RAW)); >@@ -774,10 +790,19 @@ > expectedProblemAttributes.put("RedefinedLocal", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); > expectedProblemAttributes.put("RedundantSpecificationOfTypeArguments", new ProblemAttributes(CategorizedProblem.CAT_UNNECESSARY_CODE)); > expectedProblemAttributes.put("RedundantLocalVariableNullAssignment", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); >+ expectedProblemAttributes.put("RedundantNullAnnotation", new ProblemAttributes(CategorizedProblem.CAT_UNNECESSARY_CODE)); > expectedProblemAttributes.put("RedundantNullCheckOnNonNullLocalVariable", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); >+ expectedProblemAttributes.put("RedundantNullCheckOnNonNullMessageSend", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); > expectedProblemAttributes.put("RedundantNullCheckOnNullLocalVariable", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); >+ expectedProblemAttributes.put("RedundantNullDefaultAnnotation", new ProblemAttributes(CategorizedProblem.CAT_UNNECESSARY_CODE)); >+ expectedProblemAttributes.put("RedundantNullDefaultAnnotationPackage", new ProblemAttributes(CategorizedProblem.CAT_UNNECESSARY_CODE)); >+ expectedProblemAttributes.put("RedundantNullDefaultAnnotationType", new ProblemAttributes(CategorizedProblem.CAT_UNNECESSARY_CODE)); >+ expectedProblemAttributes.put("RedundantNullDefaultAnnotationMethod", new ProblemAttributes(CategorizedProblem.CAT_UNNECESSARY_CODE)); > expectedProblemAttributes.put("RedundantSuperinterface", new ProblemAttributes(CategorizedProblem.CAT_UNNECESSARY_CODE)); > expectedProblemAttributes.put("ReferenceToForwardField", new ProblemAttributes(CategorizedProblem.CAT_MEMBER)); >+ expectedProblemAttributes.put("RequiredNonNullButProvidedNull", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); >+ expectedProblemAttributes.put("RequiredNonNullButProvidedPotentialNull", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); >+ expectedProblemAttributes.put("RequiredNonNullButProvidedUnknown", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); > expectedProblemAttributes.put("ReferenceToForwardTypeVariable", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); > expectedProblemAttributes.put("ResourceHasToImplementAutoCloseable", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); > expectedProblemAttributes.put("ReturnTypeAmbiguous", DEPRECATED); >@@ -804,6 +829,7 @@ > expectedProblemAttributes.put("SuperclassNotFound", DEPRECATED); > expectedProblemAttributes.put("SuperclassNotVisible", DEPRECATED); > expectedProblemAttributes.put("SuperfluousSemicolon", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); >+ expectedProblemAttributes.put("SwitchOnEnumNotBelow15", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); > expectedProblemAttributes.put("SwitchOnStringsNotBelow17", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); > expectedProblemAttributes.put("Task", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); > expectedProblemAttributes.put("ThisInStaticContext", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); >@@ -828,6 +854,8 @@ > expectedProblemAttributes.put("TypeMissingDeprecatedAnnotation", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE)); > expectedProblemAttributes.put("TypeParameterHidingType", new ProblemAttributes(CategorizedProblem.CAT_NAME_SHADOWING_CONFLICT)); > expectedProblemAttributes.put("UnboxingConversion", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE)); >+ expectedProblemAttributes.put("UnclosedCloseable", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); >+ expectedProblemAttributes.put("UnclosedCloseableAtExit", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); > expectedProblemAttributes.put("UndefinedAnnotationMember", new ProblemAttributes(CategorizedProblem.CAT_MEMBER)); > expectedProblemAttributes.put("UndefinedConstructor", new ProblemAttributes(CategorizedProblem.CAT_MEMBER)); > expectedProblemAttributes.put("UndefinedConstructorInDefaultConstructor", new ProblemAttributes(CategorizedProblem.CAT_MEMBER)); >@@ -887,6 +915,8 @@ > expectedProblemAttributes.put("UsingDeprecatedField", new ProblemAttributes(CategorizedProblem.CAT_DEPRECATION)); > expectedProblemAttributes.put("UsingDeprecatedMethod", new ProblemAttributes(CategorizedProblem.CAT_DEPRECATION)); > expectedProblemAttributes.put("UsingDeprecatedType", new ProblemAttributes(CategorizedProblem.CAT_DEPRECATION)); >+ expectedProblemAttributes.put("VarargsElementTypeNotVisible", new ProblemAttributes(CategorizedProblem.CAT_MEMBER)); >+ expectedProblemAttributes.put("VarargsElementTypeNotVisibleForConstructor", new ProblemAttributes(CategorizedProblem.CAT_MEMBER)); > expectedProblemAttributes.put("VarargsConflict", new ProblemAttributes(CategorizedProblem.CAT_MEMBER)); > expectedProblemAttributes.put("VariableTypeCannotBeVoid", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); > expectedProblemAttributes.put("VariableTypeCannotBeVoidArray", DEPRECATED); >@@ -1047,6 +1077,7 @@ > expectedProblemAttributes.put("CannotExtendEnum", SKIP); > expectedProblemAttributes.put("CannotHideAnInstanceMethodWithAStaticMethod", SKIP); > expectedProblemAttributes.put("CannotImportPackage", SKIP); >+ expectedProblemAttributes.put("CannotImplementIncompatibleNullness", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_SPECIFICATION_VIOLATION)); > expectedProblemAttributes.put("CannotInferElidedTypes", SKIP); > expectedProblemAttributes.put("CannotInvokeSuperConstructorInEnum", SKIP); > expectedProblemAttributes.put("CannotOverrideAStaticMethodWithAnInstanceMethod", SKIP); >@@ -1063,6 +1094,7 @@ > expectedProblemAttributes.put("CodeSnippetMissingMethod", SKIP); > expectedProblemAttributes.put("ComparingIdentical", new ProblemAttributes(JavaCore.COMPILER_PB_COMPARING_IDENTICAL)); > expectedProblemAttributes.put("ConflictingImport", SKIP); >+ expectedProblemAttributes.put("ContradictoryNullAnnotations", SKIP); > expectedProblemAttributes.put("ConstructorVarargsArgumentNeedCast", new ProblemAttributes(JavaCore.COMPILER_PB_VARARGS_ARGUMENT_NEED_CAST)); > expectedProblemAttributes.put("CorruptedSignature", SKIP); > expectedProblemAttributes.put("DeadCode", new ProblemAttributes(JavaCore.COMPILER_PB_DEAD_CODE)); >@@ -1108,6 +1140,7 @@ > expectedProblemAttributes.put("ExceptionTypeInternalNameProvided", SKIP); > expectedProblemAttributes.put("ExceptionTypeNotFound", SKIP); > expectedProblemAttributes.put("ExceptionTypeNotVisible", SKIP); >+ expectedProblemAttributes.put("ExplicitlyClosedAutoCloseable", new ProblemAttributes(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE)); > expectedProblemAttributes.put("ExpressionShouldBeAVariable", SKIP); > expectedProblemAttributes.put("ExternalProblemFixable", SKIP); > expectedProblemAttributes.put("ExternalProblemNotFixable", SKIP); >@@ -1135,8 +1168,10 @@ > expectedProblemAttributes.put("HierarchyHasProblems", SKIP); > expectedProblemAttributes.put("IllegalAbstractModifierCombinationForMethod", SKIP); > expectedProblemAttributes.put("IllegalAccessFromTypeVariable", SKIP); >+ expectedProblemAttributes.put("IllegalAnnotationForBaseType", SKIP); > expectedProblemAttributes.put("IllegalCast", SKIP); > expectedProblemAttributes.put("IllegalClassLiteralForTypeVariable", SKIP); >+ expectedProblemAttributes.put("IllegalDefinitionToNonNullParameter", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_SPECIFICATION_VIOLATION)); > expectedProblemAttributes.put("IllegalDimension", SKIP); > expectedProblemAttributes.put("IllegalEnclosingInstanceSpecification", SKIP); > expectedProblemAttributes.put("IllegalExtendedDimensions", SKIP); >@@ -1171,6 +1206,8 @@ > expectedProblemAttributes.put("IllegalPrimitiveOrArrayTypeForEnclosingInstance", SKIP); > expectedProblemAttributes.put("IllegalQualifiedEnumConstantLabel", SKIP); > expectedProblemAttributes.put("IllegalQualifiedParameterizedTypeAllocation", SKIP); >+ expectedProblemAttributes.put("IllegalRedefinitionToNonNullParameter", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_SPECIFICATION_VIOLATION)); >+ expectedProblemAttributes.put("IllegalReturnNullityRedefinition", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_SPECIFICATION_VIOLATION)); > expectedProblemAttributes.put("IllegalStaticModifierForMemberType", SKIP); > expectedProblemAttributes.put("IllegalTypeVariableSuperReference", SKIP); > expectedProblemAttributes.put("IllegalUnderscorePosition", SKIP); >@@ -1410,6 +1447,8 @@ > expectedProblemAttributes.put("PackageCollidesWithType", SKIP); > expectedProblemAttributes.put("PackageIsNotExpectedPackage", SKIP); > expectedProblemAttributes.put("ParameterAssignment", new ProblemAttributes(JavaCore.COMPILER_PB_PARAMETER_ASSIGNMENT)); >+ expectedProblemAttributes.put("ParameterLackingNonNullAnnotation", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_SPECIFICATION_VIOLATION)); >+ expectedProblemAttributes.put("ParameterLackingNullableAnnotation", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_SPECIFICATION_VIOLATION)); > expectedProblemAttributes.put("ParameterMismatch", SKIP); > expectedProblemAttributes.put("ParameterizedConstructorArgumentTypeMismatch", SKIP); > expectedProblemAttributes.put("ParameterizedMethodArgumentTypeMismatch", SKIP); >@@ -1433,7 +1472,10 @@ > expectedProblemAttributes.put("PolymorphicMethodNotBelow17", SKIP); > expectedProblemAttributes.put("PossibleAccidentalBooleanAssignment", new ProblemAttributes(JavaCore.COMPILER_PB_POSSIBLE_ACCIDENTAL_BOOLEAN_ASSIGNMENT)); > expectedProblemAttributes.put("PotentialHeapPollutionFromVararg", new ProblemAttributes(JavaCore.COMPILER_PB_UNCHECKED_TYPE_OPERATION)); >+ expectedProblemAttributes.put("PotentiallyUnclosedCloseable", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE)); >+ expectedProblemAttributes.put("PotentiallyUnclosedCloseableAtExit", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE)); > expectedProblemAttributes.put("PotentialNullLocalVariableReference", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIAL_NULL_REFERENCE)); >+ expectedProblemAttributes.put("PotentialNullMessageSendReference", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIAL_NULL_REFERENCE)); > expectedProblemAttributes.put("PublicClassMustMatchFileName", SKIP); > expectedProblemAttributes.put("RawMemberTypeCannotBeParameterized", SKIP); > expectedProblemAttributes.put("RawTypeReference", new ProblemAttributes(JavaCore.COMPILER_PB_RAW_TYPE_REFERENCE)); >@@ -1442,11 +1484,20 @@ > expectedProblemAttributes.put("RedefinedLocal", SKIP); > expectedProblemAttributes.put("RedundantSpecificationOfTypeArguments", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_TYPE_ARGUMENTS)); > expectedProblemAttributes.put("RedundantLocalVariableNullAssignment", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK)); >+ expectedProblemAttributes.put("RedundantNullAnnotation", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_ANNOTATION)); > expectedProblemAttributes.put("RedundantNullCheckOnNonNullLocalVariable", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK)); >+ expectedProblemAttributes.put("RedundantNullCheckOnNonNullMessageSend", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK)); > expectedProblemAttributes.put("RedundantNullCheckOnNullLocalVariable", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK)); >+ expectedProblemAttributes.put("RedundantNullDefaultAnnotation", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_ANNOTATION)); >+ expectedProblemAttributes.put("RedundantNullDefaultAnnotationPackage", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_ANNOTATION)); >+ expectedProblemAttributes.put("RedundantNullDefaultAnnotationType", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_ANNOTATION)); >+ expectedProblemAttributes.put("RedundantNullDefaultAnnotationMethod", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_ANNOTATION)); > expectedProblemAttributes.put("RedundantSuperinterface", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_SUPERINTERFACE)); > expectedProblemAttributes.put("ReferenceToForwardField", SKIP); > expectedProblemAttributes.put("ReferenceToForwardTypeVariable", SKIP); >+ expectedProblemAttributes.put("RequiredNonNullButProvidedNull", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_SPECIFICATION_VIOLATION)); >+ expectedProblemAttributes.put("RequiredNonNullButProvidedPotentialNull", new ProblemAttributes(JavaCore.COMPILER_PB_POTENTIAL_NULL_SPECIFICATION_VIOLATION)); >+ expectedProblemAttributes.put("RequiredNonNullButProvidedUnknown", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO)); > expectedProblemAttributes.put("ResourceHasToImplementAutoCloseable", SKIP); > expectedProblemAttributes.put("ReturnTypeAmbiguous", SKIP); > expectedProblemAttributes.put("ReturnTypeCannotBeVoidArray", SKIP); >@@ -1472,6 +1523,7 @@ > expectedProblemAttributes.put("SuperclassNotFound", SKIP); > expectedProblemAttributes.put("SuperclassNotVisible", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_SUPERINTERFACE)); > expectedProblemAttributes.put("SuperfluousSemicolon", new ProblemAttributes(JavaCore.COMPILER_PB_EMPTY_STATEMENT)); >+ expectedProblemAttributes.put("SwitchOnEnumNotBelow15", SKIP); > expectedProblemAttributes.put("SwitchOnStringsNotBelow17", SKIP); > expectedProblemAttributes.put("Task", SKIP); > expectedProblemAttributes.put("ThisInStaticContext", SKIP); >@@ -1496,6 +1548,8 @@ > expectedProblemAttributes.put("TypeMissingDeprecatedAnnotation", new ProblemAttributes(JavaCore.COMPILER_PB_MISSING_DEPRECATED_ANNOTATION)); > expectedProblemAttributes.put("TypeParameterHidingType", new ProblemAttributes(JavaCore.COMPILER_PB_TYPE_PARAMETER_HIDING)); > expectedProblemAttributes.put("UnboxingConversion", new ProblemAttributes(JavaCore.COMPILER_PB_AUTOBOXING)); >+ expectedProblemAttributes.put("UnclosedCloseable", new ProblemAttributes(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE)); >+ expectedProblemAttributes.put("UnclosedCloseableAtExit", new ProblemAttributes(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE)); > expectedProblemAttributes.put("UndefinedAnnotationMember", SKIP); > expectedProblemAttributes.put("UndefinedConstructor", SKIP); > expectedProblemAttributes.put("UndefinedConstructorInDefaultConstructor", SKIP); >@@ -1556,6 +1610,8 @@ > expectedProblemAttributes.put("UsingDeprecatedMethod", new ProblemAttributes(JavaCore.COMPILER_PB_DEPRECATION)); > expectedProblemAttributes.put("UsingDeprecatedType", new ProblemAttributes(JavaCore.COMPILER_PB_DEPRECATION)); > expectedProblemAttributes.put("VarargsConflict", SKIP); >+ expectedProblemAttributes.put("VarargsElementTypeNotVisible", SKIP); >+ expectedProblemAttributes.put("VarargsElementTypeNotVisibleForConstructor", SKIP); > expectedProblemAttributes.put("VariableTypeCannotBeVoid", SKIP); > expectedProblemAttributes.put("VariableTypeCannotBeVoidArray", SKIP); > expectedProblemAttributes.put("VoidMethodReturnsValue", SKIP); >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ConstantTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ConstantTest.java >index 66eeb0d..f63a060 100644 >--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ConstantTest.java >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ConstantTest.java >@@ -1119,7 +1119,7 @@ > "1. ERROR in X.java (at line 4)\n" + > " static final String notAConstant = null;\n" + > " ^^^^^^^^^^^^\n" + >- "The field notAConstant cannot be declared static; static fields can only be declared in static or top level types\n" + >+ "The field notAConstant cannot be declared static in a non-static inner type, unless initialized with a constant expression\n" + > "----------\n"); > } > public void testAllConstants() { >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java >index b9f580f..5e591cc 100644 >--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java >@@ -1,12 +1,13 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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: >- * IBM Corporation - initial API and implementation >+ * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contribution for Bug 365519 - editorial cleanup after bug 186342 and bug 365387 > *******************************************************************************/ > package org.eclipse.jdt.core.tests.compiler.regression; > >@@ -15,6 +16,7 @@ > > import junit.framework.Test; > >+import org.eclipse.jdt.core.JavaCore; > import org.eclipse.jdt.core.ToolFactory; > import org.eclipse.jdt.core.tests.util.Util; > import org.eclipse.jdt.core.util.ClassFileBytesDisassembler; >@@ -3761,7 +3763,7 @@ > "1. ERROR in X.java (at line 3)\n" + > " static int bar;\n" + > " ^^^\n" + >- "The field bar cannot be declared static; static fields can only be declared in static or top level types\n" + >+ "The field bar cannot be declared static in a non-static inner type, unless initialized with a constant expression\n" + > "----------\n"); > } > //https://bugs.eclipse.org/bugs/show_bug.cgi?id=99428 and https://bugs.eclipse.org/bugs/show_bug.cgi?id=99655 >@@ -6517,6 +6519,66 @@ > "", > null); > } >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=289892 >+// in interaction with null annotations >+// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=365519#c4 item (6) >+public void test180a() { >+ Map options = getCompilerOptions(); >+ options.put(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED); >+ this.runConformTest( >+ new String[] { >+ "p/package-info.java", >+ "@p.Annot(state=p.MyEnum.BROKEN)\n" + >+ "package p;", >+ "p/Annot.java", >+ "package p;\n" + >+ "@Annot(state=MyEnum.KO)\n" + >+ "public @interface Annot {\n" + >+ " MyEnum state() default MyEnum.KO;\n" + >+ "}", >+ "p/MyEnum.java", >+ "package p;\n" + >+ "@Annot(state=MyEnum.KO)\n" + >+ "public enum MyEnum {\n" + >+ " WORKS, OK, KO, BROKEN, ;\n" + >+ "}", >+ "test180/package-info.java", >+ "@p.Annot(state=p.MyEnum.OK)\n" + >+ "package test180;", >+ "test180/Test.java", >+ "package test180;\n" + >+ "import p.MyEnum;\n" + >+ "import p.Annot;\n" + >+ "@Annot(state=MyEnum.OK)\n" + >+ "public class Test {}", >+ }, >+ "", >+ null, >+ true, >+ null, >+ options, >+ null >+ ); >+ options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_Process_Annotations, CompilerOptions.ENABLED); >+ this.runConformTest( >+ false, >+ new String[] { >+ "X.java", >+ "import test180.Test;\n" + >+ "public class X {\n" + >+ " public static void main(String[] args) {\n" + >+ " System.out.println(Test.class);\n" + >+ " }\n" + >+ "}" >+ }, >+ null, >+ options, >+ "", >+ "class test180.Test", >+ "", >+ null); >+} > //https://bugs.eclipse.org/bugs/show_bug.cgi?id=300133 > public void test181() { > this.runConformTest( >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java >index 32b50af..4e75828 100644 >--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java >@@ -7,7 +7,10 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >- * Stephan Herrmann - Contribution for bug 236385 >+ * Stephan Herrmann - Contributions for >+ * bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used >+ * bug 349326 - [1.7] new warning for missing try-with-resources >+ * bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop) > *******************************************************************************/ > package org.eclipse.jdt.core.tests.compiler.regression; > >@@ -28,6 +31,7 @@ > > public class FlowAnalysisTest extends AbstractRegressionTest { > static { >+// TESTS_NAMES = new String[] { "testLocalClassInInitializer1" }; > // TESTS_NUMBERS = new int[] { 69 }; > } > public FlowAnalysisTest(String name) { >@@ -2360,6 +2364,138 @@ > "The local variable i may not have been initialized\n" + > "----------\n"); > } >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// variant < 1.7 using Closeable: not closed >+public void testCloseable1() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.WARNING); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " FileReader fileReader = new FileReader(file); // not closed\n" + >+ " char[] in = new char[50];\n" + >+ " fileReader.read(in);\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. WARNING in X.java (at line 7)\n" + >+ " FileReader fileReader = new FileReader(file); // not closed\n" + >+ " ^^^^^^^^^^\n" + >+ "Resource leak: 'fileReader' is never closed\n" + >+ "----------\n", >+ null, true, options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// variant < 1.7 using Closeable: resource is closed, cannot suggest try-with-resources < 1.7 >+public void testCloseable2() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.WARNING); >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " FileReader fileReader = new FileReader(file); // not closed\n" + >+ " char[] in = new char[50];\n" + >+ " fileReader.read(in);\n" + >+ " fileReader.close();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "", >+ null, true, null, options, null); >+} >+// Bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop) >+// return/break/continue inside anonymous class inside try-catch inside initializer >+public void testLocalClassInInitializer1() { >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " static {\n" + >+ " final int i=4;\n" + >+ " try {\n" + >+ " Runnable runner = new Runnable() {\n" + >+ " public void run() {\n" + >+ " switch (i) {" + >+ " case 4: break;\n" + >+ " }\n" + >+ " int j = i;\n" + >+ " while (j++ < 10) {\n" + >+ " if (j == 2) continue;\n" + >+ " if (j == 4) break;\n" + >+ " if (j == 6) return;\n" + >+ " }\n" + >+ " }\n" + >+ " };\n" + >+ " } catch (RuntimeException re) {}\n" + >+ " }\n" + >+ "}\n" >+ }, >+ ""); >+} >+// Bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop) >+// break/continue illegally inside anonymous class inside loop (loop is out of scope for break/continue) >+public void testLocalClassInInitializer2() { >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " void f () {\n" + >+ " while (true) {\n" + >+ " class Inner1 {\n" + >+ " { if (true) break; }\n" + >+ " }\n" + >+ " new Inner1();\n" + >+ " }\n" + >+ " } \n" + >+ " void g () {\n" + >+ " outer: for (int i=1;true;i++) {\n" + >+ " class Inner2 {\n" + >+ " int j = 3;\n" + >+ " void foo () {\n" + >+ " if (2 == j) continue outer;\n" + >+ " else continue;\n" + >+ " }\n" + >+ " }\n" + >+ " new Inner2().foo();\n" + >+ " }\n" + >+ " } \n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 5)\n" + >+ " { if (true) break; }\n" + >+ " ^^^^^^\n" + >+ "break cannot be used outside of a loop or a switch\n" + >+ "----------\n" + >+ "2. WARNING in X.java (at line 11)\n" + >+ " outer: for (int i=1;true;i++) {\n" + >+ " ^^^^^\n" + >+ "The label outer is never explicitly referenced\n" + >+ "----------\n" + >+ "3. ERROR in X.java (at line 15)\n" + >+ " if (2 == j) continue outer;\n" + >+ " ^^^^^^^^^^^^^^^\n" + >+ "The label outer is missing\n" + >+ "----------\n" + >+ "4. ERROR in X.java (at line 16)\n" + >+ " else continue;\n" + >+ " ^^^^^^^^^\n" + >+ "continue cannot be used outside of a loop\n" + >+ "----------\n"); >+} > public static Class testClass() { > return FlowAnalysisTest.class; > } >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java >index 3c54f5f..f2968e4 100644 >--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -2465,4 +2465,88 @@ > "\'<>\' operator is not allowed for source level below 1.7\n" + > "----------\n"); > } >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=366131 >+public void test366131() { >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " public static void main(String [] args) {\n" + >+ " System.out.println(\"SUCCESS\");\n" + >+ " }\n" + >+ "}\n" + >+ "class Range<T extends Comparable<? super T>> {\n" + >+ " public boolean containsNC(T value) {\n" + >+ " return false;\n" + >+ " }\n" + >+ "}\n" + >+ "class NumberRange<T extends Number & Comparable<? super T>> extends Range<T> {\n" + >+ " public boolean contains(Comparable<?> value) {\n" + >+ " return castTo((Class) null).containsNC((Comparable) null);\n" + >+ " }\n" + >+ " public <N extends Number & Comparable<? super N>> NumberRange<N>\n" + >+ "castTo(Class<N> type) {\n" + >+ " return null;\n" + >+ " }\n" + >+ "}\n", >+ }, >+ "SUCCESS"); >+} >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=366131 >+public void test366131b() { >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " public static void main(String [] args) {\n" + >+ " Zork z;\n" + >+ " }\n" + >+ "}\n" + >+ "class Range<T extends Comparable<? super T>> {\n" + >+ " public boolean containsNC(T value) {\n" + >+ " return false;\n" + >+ " }\n" + >+ "}\n" + >+ "class NumberRange<T extends Number & Comparable<? super T>> extends Range<T> {\n" + >+ " public boolean contains(Comparable<?> value) {\n" + >+ " return castTo((Class) null).containsNC((Comparable) null);\n" + >+ " }\n" + >+ " public <N extends Number & Comparable<? super N>> NumberRange<N>\n" + >+ "castTo(Class<N> type) {\n" + >+ " return null;\n" + >+ " }\n" + >+ "}\n", >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 3)\n" + >+ " Zork z;\n" + >+ " ^^^^\n" + >+ "Zork cannot be resolved to a type\n" + >+ "----------\n" + >+ "2. WARNING in X.java (at line 13)\n" + >+ " return castTo((Class) null).containsNC((Comparable) null);\n" + >+ " ^^^^^^^^^^^^^^^^^^^^\n" + >+ "Type safety: Unchecked invocation castTo(Class) of the generic method castTo(Class<N>) of type NumberRange<T>\n" + >+ "----------\n" + >+ "3. WARNING in X.java (at line 13)\n" + >+ " return castTo((Class) null).containsNC((Comparable) null);\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Type safety: The method containsNC(Comparable) belongs to the raw type Range. References to generic type Range<T> should be parameterized\n" + >+ "----------\n" + >+ "4. WARNING in X.java (at line 13)\n" + >+ " return castTo((Class) null).containsNC((Comparable) null);\n" + >+ " ^^^^^^^^^^^^\n" + >+ "Type safety: The expression of type Class needs unchecked conversion to conform to Class<Number&Comparable<? super Number&Comparable<? super N>>>\n" + >+ "----------\n" + >+ "5. WARNING in X.java (at line 13)\n" + >+ " return castTo((Class) null).containsNC((Comparable) null);\n" + >+ " ^^^^^\n" + >+ "Class is a raw type. References to generic type Class<T> should be parameterized\n" + >+ "----------\n" + >+ "6. WARNING in X.java (at line 13)\n" + >+ " return castTo((Class) null).containsNC((Comparable) null);\n" + >+ " ^^^^^^^^^^\n" + >+ "Comparable is a raw type. References to generic type Comparable<T> should be parameterized\n" + >+ "----------\n"); >+} > } >\ No newline at end of file >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_7.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_7.java >index 4fddfd8..c79521e 100644 >--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_7.java >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_7.java >@@ -2302,6 +2302,28 @@ > false, > customOptions); > } >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=361441 >+public void test0061() { >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.net.URI;" + >+ "import java.nio.file.FileSystems;" + >+ "import java.util.Collections;\n" + >+ "public class X {\n" + >+ " public static void foo() {\n" + >+ " URI uri = URI.create(\"http://www.eclipse.org\");\n" + >+ " FileSystems.<String, Object>newFileSystem(uri, Collections.emptyMap());\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 5)\n" + >+ " FileSystems.<String, Object>newFileSystem(uri, Collections.emptyMap());\n" + >+ " ^^^^^^^^^^^^^\n" + >+ "The method newFileSystem(URI, Map<String,?>) in the type FileSystems is not applicable for the arguments (URI, Map<Object,Object>)\n" + >+ "----------\n"); >+} > public static Class testClass() { > return GenericsRegressionTest_1_7.class; > } >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LookupTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LookupTest.java >index a1e545c..a53b3e5 100644 >--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LookupTest.java >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LookupTest.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -3459,6 +3459,36 @@ > "The value of the field A.C.x is not used\n" + > "----------\n"); > } >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=350738 >+public void test106() { >+ if (this.complianceLevel < ClassFileConstants.JDK1_5) >+ return; >+ this.runNegativeTest( >+ new String[] { >+ "X.java",//------------------------------ >+ "import java.util.List;\n" + >+ "import java.util.Set;\n" + >+ "public class X {\n" + >+ " private static List<Object> foo1(Set<Object> set) {\n" + >+ " return foo1(set);\n" + >+ " }\n" + >+ " private static <T> List<T> foo3(Set<T> set) {\n" + >+ " return foo3(set);\n" + >+ " }\n" + >+ "}\n", >+ }, >+ "----------\n" + >+ "1. WARNING in X.java (at line 4)\n" + >+ " private static List<Object> foo1(Set<Object> set) {\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^\n" + >+ "The method foo1(Set<Object>) from the type X is never used locally\n" + >+ "----------\n" + >+ "2. WARNING in X.java (at line 7)\n" + >+ " private static <T> List<T> foo3(Set<T> set) {\n" + >+ " ^^^^^^^^^^^^^^^^\n" + >+ "The method foo3(Set<T>) from the type X is never used locally\n" + >+ "----------\n"); >+} > public static Class testClass() { return LookupTest.class; > } > } >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java >index 56c50ae..53f8c5b 100644 >--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -2330,18 +2330,36 @@ > // https://bugs.eclipse.org/bugs/show_bug.cgi?id=83162 > public void test036d() { // 2 interface cases > // in these cases, bridge methods are needed once abstract/concrete methods are defiined (either in the abstract class or a concrete subclass) >- this.runConformTest( >- new String[] { >- "Y.java", >- "abstract class Y implements Equivalent<String>, EqualityComparable<Integer> {\n" + >- " public abstract boolean equalTo(Number other);\n" + >- "}\n" + >- "interface Equivalent<T> { boolean equalTo(T other); }\n" + >- "interface EqualityComparable<T> { boolean equalTo(T other); }\n" >- }, >- "" >- // no bridge methods are created here since Y does not define an equalTo(?) method which equals an inherited equalTo method >- ); >+ if (this.complianceLevel < ClassFileConstants.JDK1_7) { >+ this.runConformTest( >+ new String[] { >+ "Y.java", >+ "abstract class Y implements Equivalent<String>, EqualityComparable<Integer> {\n" + >+ " public abstract boolean equalTo(Number other);\n" + >+ "}\n" + >+ "interface Equivalent<T> { boolean equalTo(T other); }\n" + >+ "interface EqualityComparable<T> { boolean equalTo(T other); }\n" >+ }, >+ "" >+ // no bridge methods are created here since Y does not define an equalTo(?) method which equals an inherited equalTo method >+ ); >+ } else { >+ this.runNegativeTest( >+ new String[] { >+ "Y.java", >+ "abstract class Y implements Equivalent<String>, EqualityComparable<Integer> {\n" + >+ " public abstract boolean equalTo(Number other);\n" + >+ "}\n" + >+ "interface Equivalent<T> { boolean equalTo(T other); }\n" + >+ "interface EqualityComparable<T> { boolean equalTo(T other); }\n" >+ }, >+ "----------\n" + >+ "1. ERROR in Y.java (at line 1)\n" + >+ " abstract class Y implements Equivalent<String>, EqualityComparable<Integer> {\n" + >+ " ^\n" + >+ "Name clash: The method equalTo(T) of type Equivalent<T> has the same erasure as equalTo(T) of type EqualityComparable<T> but does not override it\n" + >+ "----------\n"); >+ } > } > // https://bugs.eclipse.org/bugs/show_bug.cgi?id=83162 > public void test036e() { // 2 interface cases >@@ -2354,6 +2372,7 @@ > "interface Equivalent<T> { boolean equalTo(T other); }\n" + > "interface EqualityComparable<T> { boolean equalTo(T other); }\n" > }, >+ this.complianceLevel < ClassFileConstants.JDK1_7 ? > "----------\n" + > "1. ERROR in Y.java (at line 2)\n" + > " public abstract boolean equalTo(Object other);\n" + >@@ -2364,8 +2383,24 @@ > " public abstract boolean equalTo(Object other);\n" + > " ^^^^^^^^^^^^^^^^^^^^^\n" + > "Name clash: The method equalTo(Object) of type Y has the same erasure as equalTo(T) of type EqualityComparable<T> but does not override it\n" + >- "----------\n" >+ "----------\n" : > // name clash: equalTo(java.lang.Object) in Y and equalTo(T) in Equivalent<java.lang.String> have the same erasure, yet neither overrides the other >+ "----------\n" + >+ "1. ERROR in Y.java (at line 1)\n" + >+ " abstract class Y implements Equivalent<String>, EqualityComparable<Integer> {\n" + >+ " ^\n" + >+ "Name clash: The method equalTo(T) of type Equivalent<T> has the same erasure as equalTo(T) of type EqualityComparable<T> but does not override it\n" + >+ "----------\n" + >+ "2. ERROR in Y.java (at line 2)\n" + >+ " public abstract boolean equalTo(Object other);\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Name clash: The method equalTo(Object) of type Y has the same erasure as equalTo(T) of type Equivalent<T> but does not override it\n" + >+ "----------\n" + >+ "3. ERROR in Y.java (at line 2)\n" + >+ " public abstract boolean equalTo(Object other);\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Name clash: The method equalTo(Object) of type Y has the same erasure as equalTo(T) of type EqualityComparable<T> but does not override it\n" + >+ "----------\n" > ); > } > // https://bugs.eclipse.org/bugs/show_bug.cgi?id=83162 >@@ -2428,6 +2463,7 @@ > "interface K extends I { void foo(A<String> a); }\n" + > "class A<T> {}" > }, >+ this.complianceLevel < ClassFileConstants.JDK1_7 ? > "----------\n" + > "1. WARNING in X.java (at line 4)\n" + > " class YYY implements J, I { public void foo(A a) {} }\n" + >@@ -2453,7 +2489,38 @@ > " interface K extends I { void foo(A<String> a); }\n" + > " ^^^^^^^^^^^^^^^^\n" + > "Name clash: The method foo(A<String>) of type K has the same erasure as foo(A) of type I but does not override it\n" + >- "----------\n"); >+ "----------\n" : >+ "----------\n" + >+ "1. ERROR in X.java (at line 2)\n" + >+ " abstract class Y implements J, I { }\n" + >+ " ^\n" + >+ "Name clash: The method foo(A<String>) of type J has the same erasure as foo(A) of type I but does not override it\n" + >+ "----------\n" + >+ "2. WARNING in X.java (at line 4)\n" + >+ " class YYY implements J, I { public void foo(A a) {} }\n" + >+ " ^\n" + >+ "A is a raw type. References to generic type A<T> should be parameterized\n" + >+ "----------\n" + >+ "3. WARNING in X.java (at line 5)\n" + >+ " class XXX implements I, J { public void foo(A a) {} }\n" + >+ " ^\n" + >+ "A is a raw type. References to generic type A<T> should be parameterized\n" + >+ "----------\n" + >+ "4. WARNING in X.java (at line 6)\n" + >+ " class ZZZ implements K { public void foo(A a) {} }\n" + >+ " ^\n" + >+ "A is a raw type. References to generic type A<T> should be parameterized\n" + >+ "----------\n" + >+ "5. WARNING in X.java (at line 7)\n" + >+ " interface I { void foo(A a); }\n" + >+ " ^\n" + >+ "A is a raw type. References to generic type A<T> should be parameterized\n" + >+ "----------\n" + >+ "6. ERROR in X.java (at line 9)\n" + >+ " interface K extends I { void foo(A<String> a); }\n" + >+ " ^^^^^^^^^^^^^^^^\n" + >+ "Name clash: The method foo(A<String>) of type K has the same erasure as foo(A) of type I but does not override it\n" + >+ "----------\n"); > } > public void test037a() { // test inheritance scenarios > this.runNegativeTest( >@@ -11238,25 +11305,7 @@ > } > //https://bugs.eclipse.org/bugs/show_bug.cgi?id=285088 > public void test200() { >- Map options = getCompilerOptions(); >- String compliance = (String) options.get(JavaCore.COMPILER_COMPLIANCE); >- String errorMessage = compliance == JavaCore.VERSION_1_6 ? >- "----------\n" + >- "1. WARNING in X.java (at line 3)\n" + >- " int foo(Collection bar) { return 0; }\n" + >- " ^^^^^^^^^^^^^^^^^^^\n" + >- "Method foo(Collection) has the same erasure foo(Collection<E>) as another method in type X\n" + >- "----------\n" + >- "2. WARNING in X.java (at line 3)\n" + >- " int foo(Collection bar) { return 0; }\n" + >- " ^^^^^^^^^^\n" + >- "Collection is a raw type. References to generic type Collection<E> should be parameterized\n" + >- "----------\n" + >- "3. WARNING in X.java (at line 4)\n" + >- " double foo(Collection<String> bar) {return 0; }\n" + >- " ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >- "Method foo(Collection<String>) has the same erasure foo(Collection<E>) as another method in type X\n" + >- "----------\n" : >+ String errorMessage = > "----------\n" + > "1. ERROR in X.java (at line 3)\n" + > " int foo(Collection bar) { return 0; }\n" + >@@ -13439,7 +13488,7 @@ > String output = this.complianceLevel == ClassFileConstants.JDK1_6 ? > "----------\n" + > "1. WARNING in Test.java (at line 3)\n" + >- " public class Test<Key, Value> extends LinkedHashMap<Key, Collection<Value>> {\n" + >+ " public class Test<Key, Value> extends HashMap<Key, Collection<Value>> {\n" + > " ^^^^\n" + > "The serializable class Test does not declare a static final serialVersionUID field of type long\n" + > "----------\n" + >@@ -13451,7 +13500,7 @@ > "3. WARNING in Test.java (at line 5)\n" + > " public Collection<Value> get(Key k) { return null; }\n" + > " ^^^^^^^^^^\n" + >- "Name clash: The method get(Key) of type Test<Key,Value> has the same erasure as get(Object) of type LinkedHashMap<K,V> but does not override it\n" + >+ "Name clash: The method get(Key) of type Test<Key,Value> has the same erasure as get(Object) of type HashMap<K,V> but does not override it\n" + > "----------\n" + > "4. ERROR in Test.java (at line 6)\n" + > " Zork z;\n" + >@@ -13460,7 +13509,7 @@ > "----------\n": > "----------\n" + > "1. WARNING in Test.java (at line 3)\n" + >- " public class Test<Key, Value> extends LinkedHashMap<Key, Collection<Value>> {\n" + >+ " public class Test<Key, Value> extends HashMap<Key, Collection<Value>> {\n" + > " ^^^^\n" + > "The serializable class Test does not declare a static final serialVersionUID field of type long\n" + > "----------\n" + >@@ -13472,7 +13521,7 @@ > "3. ERROR in Test.java (at line 5)\n" + > " public Collection<Value> get(Key k) { return null; }\n" + > " ^^^^^^^^^^\n" + >- "Name clash: The method get(Key) of type Test<Key,Value> has the same erasure as get(Object) of type LinkedHashMap<K,V> but does not override it\n" + >+ "Name clash: The method get(Key) of type Test<Key,Value> has the same erasure as get(Object) of type HashMap<K,V> but does not override it\n" + > "----------\n" + > "4. ERROR in Test.java (at line 6)\n" + > " Zork z;\n" + >@@ -13483,8 +13532,8 @@ > new String[] { > "Test.java", > "import java.util.Collection;\n" + >- "import java.util.LinkedHashMap;\n" + >- "public class Test<Key, Value> extends LinkedHashMap<Key, Collection<Value>> {\n" + >+ "import java.util.HashMap;\n" + >+ "public class Test<Key, Value> extends HashMap<Key, Collection<Value>> {\n" + > " public Collection<Value> put(Key k, Value v) { return null; }\n" + > " public Collection<Value> get(Key k) { return null; }\n" + > " Zork z;\n" + >@@ -13512,4 +13561,253 @@ > "Name clash: The method foo(A<Integer>) of type Sub has the same erasure as foo(A<Number>) of type Super but does not hide it\n" + > "----------\n"); > } >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=355838 >+public void testBug355838() throws Exception { >+ String output = >+ "----------\n" + >+ "1. ERROR in ErasureBug.java (at line 4)\n" + >+ " public String output(List<String> integers) {\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Method output(List<String>) has the same erasure output(List<E>) as another method in type ErasureBug\n" + >+ "----------\n" + >+ "2. ERROR in ErasureBug.java (at line 7)\n" + >+ " public String output(List doubles) {\n" + >+ " ^^^^^^^^^^^^^^^^^^^^\n" + >+ "Method output(List) has the same erasure output(List<E>) as another method in type ErasureBug\n" + >+ "----------\n" + >+ "3. WARNING in ErasureBug.java (at line 7)\n" + >+ " public String output(List doubles) {\n" + >+ " ^^^^\n" + >+ "List is a raw type. References to generic type List<E> should be parameterized\n" + >+ "----------\n" + >+ "4. WARNING in ErasureBug.java (at line 10)\n" + >+ " public static void main(String[] args) { new ErasureBug().output(new ArrayList()); }\n" + >+ " ^^^^^^^^^^^^^^^\n" + >+ "Type safety: The expression of type ArrayList needs unchecked conversion to conform to List<String>\n" + >+ "----------\n" + >+ "5. WARNING in ErasureBug.java (at line 10)\n" + >+ " public static void main(String[] args) { new ErasureBug().output(new ArrayList()); }\n" + >+ " ^^^^^^^^^\n" + >+ "ArrayList is a raw type. References to generic type ArrayList<E> should be parameterized\n" + >+ "----------\n"; >+ this.runNegativeTest( >+ new String[] { >+ "ErasureBug.java", >+ "import java.util.ArrayList;\n" + >+ "import java.util.List;\n" + >+ "public class ErasureBug {\n" + >+ " public String output(List<String> integers) {\n" + >+ " return \"1\";\n" + >+ " }\n" + >+ " public String output(List doubles) {\n" + >+ " return \"2\";\n" + >+ " }\n" + >+ " public static void main(String[] args) { new ErasureBug().output(new ArrayList()); }\n" + >+ "}\n" >+ }, >+ output); >+} >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=288658, make sure a bridge method >+// is generated when a public method is inherited from a non-public class into a >+// public class if the non public class happens to be defined in a named package. >+public void test288658() { >+ this.runConformTest( >+ new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "import java.lang.annotation.Annotation;\n"+ >+ "import java.lang.annotation.Retention;\n"+ >+ "import java.lang.annotation.RetentionPolicy;\n"+ >+ "import java.lang.reflect.Method;\n"+ >+ "\n"+ >+ "public class Test extends Super {\n"+ >+ " public static void main(String[] args) {\n"+ >+ " try {\n"+ >+ " Method m = Test.class.getMethod(\"setFoo\", String.class);\n"+ >+ " Annotation a = m.getAnnotation(Anno.class);\n"+ >+ " System.out.println(\"Annotation was \" + (a == null ? \"not \" : \"\") +\n"+ >+ "\"found\");\n"+ >+ " } catch (Exception e) {\n"+ >+ " e.printStackTrace();\n"+ >+ " }\n"+ >+ " }\n"+ >+ "}\n"+ >+ "\n"+ >+ "class Super {\n"+ >+ " @Anno\n"+ >+ " public void setFoo(String foo) {}\n"+ >+ "}\n"+ >+ "\n"+ >+ "@Retention(RetentionPolicy.RUNTIME)\n"+ >+ "@interface Anno {\n"+ >+ "\n"+ >+ "}\n" >+ }, >+ this.complianceLevel <= ClassFileConstants.JDK1_5 ? "Annotation was found" : "Annotation was not found"); >+} >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=288658, make sure a bridge method >+// is generated when a public method is inherited from a non-public class into a >+// public class if the non public class happens to be defined in a named package. >+public void test288658a() { >+ this.runConformTest( >+ new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "import java.lang.annotation.Annotation;\n"+ >+ "import java.lang.annotation.Retention;\n"+ >+ "import java.lang.annotation.RetentionPolicy;\n"+ >+ "import java.lang.reflect.Method;\n"+ >+ "\n"+ >+ "public class Test extends Super {\n"+ >+ " public void setFoo() {}\n" + >+ " public static void main(String[] args) {\n"+ >+ " try {\n"+ >+ " Method m = Test.class.getMethod(\"setFoo\", String.class);\n"+ >+ " Annotation a = m.getAnnotation(Anno.class);\n"+ >+ " System.out.println(\"Annotation was \" + (a == null ? \"not \" : \"\") +\n"+ >+ "\"found\");\n"+ >+ " } catch (Exception e) {\n"+ >+ " e.printStackTrace();\n"+ >+ " }\n"+ >+ " }\n"+ >+ "}\n"+ >+ "\n"+ >+ "class Super {\n"+ >+ " @Anno\n"+ >+ " public void setFoo(String foo) {}\n"+ >+ "}\n"+ >+ "\n"+ >+ "@Retention(RetentionPolicy.RUNTIME)\n"+ >+ "@interface Anno {\n"+ >+ "\n"+ >+ "}\n" >+ }, >+ this.complianceLevel <= ClassFileConstants.JDK1_5 ? "Annotation was found" : "Annotation was not found"); >+} >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=354229 >+public void test354229() { >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.util.*;\n" + >+ "interface A {\n" + >+ "int get(List<String> l);\n" + >+ "}\n" + >+ "interface B {\n" + >+ "int get(List<Integer> l);\n" + >+ "}\n" + >+ "interface C extends A, B { \n" + >+ "//int get(List l); // name clash error here\n" + >+ " Zork z;\n" + >+ "}\n" >+ }, >+ this.complianceLevel <= ClassFileConstants.JDK1_6 ? >+ "----------\n" + >+ "1. ERROR in X.java (at line 10)\n" + >+ " Zork z;\n" + >+ " ^^^^\n" + >+ "Zork cannot be resolved to a type\n" + >+ "----------\n" : >+ "----------\n" + >+ "1. ERROR in X.java (at line 8)\n" + >+ " interface C extends A, B { \n" + >+ " ^\n" + >+ "Name clash: The method get(List<String>) of type A has the same erasure as get(List<Integer>) of type B but does not override it\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 10)\n" + >+ " Zork z;\n" + >+ " ^^^^\n" + >+ "Zork cannot be resolved to a type\n" + >+ "----------\n"); >+} >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=354229 >+public void test354229b() { >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.util.*;\n" + >+ "interface A {\n" + >+ "int get(List<String> l);\n" + >+ "}\n" + >+ "interface B {\n" + >+ "int get(List<Integer> l);\n" + >+ "}\n" + >+ "interface C extends A, B { \n" + >+ " int get(List l); // name clash error here\n" + >+ " Zork z;\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. WARNING in X.java (at line 9)\n" + >+ " int get(List l); // name clash error here\n" + >+ " ^^^^\n" + >+ "List is a raw type. References to generic type List<E> should be parameterized\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 10)\n" + >+ " Zork z;\n" + >+ " ^^^^\n" + >+ "Zork cannot be resolved to a type\n" + >+ "----------\n"); >+} >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=354229 >+public void test354229c() { >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "interface X {\n" + >+ " <T> T e(Action<T> p);\n" + >+ "}\n" + >+ "interface Y {\n" + >+ " <S, T> S e(Action<S> t);\n" + >+ "}\n" + >+ "interface E extends X, Y {\n" + >+ "}\n" + >+ "class Action<T> {\n" + >+ " Zork z;\n" + >+ "}\n" >+ >+ }, >+ this.complianceLevel < ClassFileConstants.JDK1_7 ? >+ "----------\n" + >+ "1. ERROR in X.java (at line 10)\n" + >+ " Zork z;\n" + >+ " ^^^^\n" + >+ "Zork cannot be resolved to a type\n" + >+ "----------\n" : >+ "----------\n" + >+ "1. ERROR in X.java (at line 7)\n" + >+ " interface E extends X, Y {\n" + >+ " ^\n" + >+ "Name clash: The method e(Action<T>) of type X has the same erasure as e(Action<S>) of type Y but does not override it\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 10)\n" + >+ " Zork z;\n" + >+ " ^^^^\n" + >+ "Zork cannot be resolved to a type\n" + >+ "----------\n"); >+} >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=354229 >+public void test354229d() { >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "interface X {\n" + >+ " <T> T e(Action<T> p);\n" + >+ " <S, T> S e(Action<S> t);\n" + >+ "}\n" + >+ "class Action<T> {\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 2)\n" + >+ " <T> T e(Action<T> p);\n" + >+ " ^^^^^^^^^^^^^^\n" + >+ "Method e(Action<T>) has the same erasure e(Action<T>) as another method in type X\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 3)\n" + >+ " <S, T> S e(Action<S> t);\n" + >+ " ^^^^^^^^^^^^^^\n" + >+ "Method e(Action<S>) has the same erasure e(Action<T>) as another method in type X\n" + >+ "----------\n"); >+} > } >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NonFatalErrorTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NonFatalErrorTest.java >index 1d28367..2db03cf 100644 >--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NonFatalErrorTest.java >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NonFatalErrorTest.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -12,6 +12,7 @@ > > import java.util.Map; > >+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; > import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; > > import junit.framework.Test; >@@ -24,7 +25,7 @@ > // All specified tests which does not belong to the class are skipped... > static { > // TESTS_NAMES = new String[] { "test127" }; >-// TESTS_NUMBERS = new int[] { 5 }; >+// TESTS_NUMBERS = new int[] { 7 }; > // TESTS_RANGE = new int[] { 169, 180 }; > } > >@@ -258,4 +259,41 @@ > // javac options > JavacTestOptions.Excuse.EclipseWarningConfiguredAsError /* javac test options */); > } >+ public void test007() { >+ if (this.complianceLevel < ClassFileConstants.JDK1_5) { >+ return; >+ } >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(CompilerOptions.OPTION_FatalOptionalError, >+ CompilerOptions.ENABLED); >+ customOptions.put(CompilerOptions.OPTION_ReportUnusedLocal, >+ CompilerOptions.ERROR); >+ customOptions.put(CompilerOptions.OPTION_SuppressWarnings, >+ CompilerOptions.ENABLED); >+ customOptions.put(CompilerOptions.OPTION_SuppressOptionalErrors, >+ CompilerOptions.ENABLED); >+ customOptions.put(CompilerOptions.OPTION_ReportUnusedWarningToken, >+ CompilerOptions.ERROR); >+ runConformTest( >+ new String[] { /* test files */ >+ "X.java", >+ "public class X {\n" + >+ " @SuppressWarnings(\"unused\")\n" + >+ " static void foo() {\n" + >+ " String s = null;\n" + >+ " System.out.println(\"SUCCESS\");\n" + >+ " }\n" + >+ " public static void main(String argv[]) {\n" + >+ " foo();\n" + >+ " }\n" + >+ "}" >+ }, >+ "SUCCESS" /* expected output string */, >+ null /* no class libraries */, >+ true, >+ null, >+ customOptions /* custom options */, >+ // compiler results >+ null /* do not check error string */); >+ } > } >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java >new file mode 100644 >index 0000000..ebd5df0 >--- /dev/null >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java >@@ -0,0 +1,3477 @@ >+/******************************************************************************* >+ * Copyright (c) 2010, 2011 GK Software AG 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: >+ * Stephan Herrmann - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.core.tests.compiler.regression; >+ >+ >+import java.io.File; >+import java.util.Map; >+ >+import junit.framework.Test; >+ >+import org.eclipse.core.runtime.FileLocator; >+import org.eclipse.core.runtime.Platform; >+import org.eclipse.jdt.core.JavaCore; >+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; >+ >+// see bug 186342 - [compiler][null] Using annotations for null checking >+public class NullAnnotationTest extends AbstractComparableTest { >+ >+// class libraries including our default null annotation types: >+String[] LIBS; >+ >+// names and content of custom annotations used in a few tests: >+private static final String CUSTOM_NONNULL_NAME = "org/foo/NonNull.java"; >+private static final String CUSTOM_NONNULL_CONTENT = >+ "package org.foo;\n" + >+ "import static java.lang.annotation.ElementType.*;\n" + >+ "import java.lang.annotation.*;\n" + >+ "@Retention(RetentionPolicy.CLASS)\n" + >+ "@Target({METHOD,PARAMETER,LOCAL_VARIABLE})\n" + >+ "public @interface NonNull {\n" + >+ "}\n"; >+private static final String CUSTOM_NULLABLE_NAME = "org/foo/Nullable.java"; >+private static final String CUSTOM_NULLABLE_CONTENT = "package org.foo;\n" + >+ "import static java.lang.annotation.ElementType.*;\n" + >+ "import java.lang.annotation.*;\n" + >+ "@Retention(RetentionPolicy.CLASS)\n" + >+ "@Target({METHOD,PARAMETER,LOCAL_VARIABLE})\n" + >+ "public @interface Nullable {\n" + >+ "}\n"; >+ >+public NullAnnotationTest(String name) { >+ super(name); >+} >+ >+// Static initializer to specify tests subset using TESTS_* static variables >+// All specified tests which do not belong to the class are skipped... >+static { >+// TESTS_NAMES = new String[] { "test_message_send_in_control_structure_02" }; >+// TESTS_NUMBERS = new int[] { 561 }; >+// TESTS_RANGE = new int[] { 1, 2049 }; >+} >+ >+public static Test suite() { >+ return buildComparableTestSuite(testClass()); >+} >+ >+public static Class testClass() { >+ return NullAnnotationTest.class; >+} >+ >+protected void setUp() throws Exception { >+ super.setUp(); >+ if (this.LIBS == null) { >+ String[] defaultLibs = getDefaultClassPaths(); >+ int len = defaultLibs.length; >+ this.LIBS = new String[len+1]; >+ System.arraycopy(defaultLibs, 0, this.LIBS, 0, len); >+ File bundleFile = FileLocator.getBundleFile(Platform.getBundle("org.eclipse.jdt.annotation")); >+ if (bundleFile.isDirectory()) >+ this.LIBS[len] = bundleFile.getPath()+"/bin"; >+ else >+ this.LIBS[len] = bundleFile.getPath(); >+ } >+} >+// Conditionally augment problem detection settings >+static boolean setNullRelatedOptions = true; >+protected Map getCompilerOptions() { >+ Map defaultOptions = super.getCompilerOptions(); >+ if (setNullRelatedOptions) { >+ defaultOptions.put(JavaCore.COMPILER_PB_NULL_REFERENCE, JavaCore.ERROR); >+ defaultOptions.put(JavaCore.COMPILER_PB_POTENTIAL_NULL_REFERENCE, JavaCore.ERROR); >+ defaultOptions.put(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK, JavaCore.ERROR); >+ defaultOptions.put(JavaCore.COMPILER_PB_INCLUDE_ASSERTS_IN_NULL_ANALYSIS, JavaCore.ENABLED); >+ >+ defaultOptions.put(JavaCore.COMPILER_PB_MISSING_OVERRIDE_ANNOTATION_FOR_INTERFACE_METHOD_IMPLEMENTATION, JavaCore.DISABLED); >+ >+ // enable null annotations: >+ defaultOptions.put(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED); >+ // leave other new options at these defaults: >+// defaultOptions.put(CompilerOptions.OPTION_ReportNullContractViolation, JavaCore.ERROR); >+// defaultOptions.put(CompilerOptions.OPTION_ReportPotentialNullContractViolation, JavaCore.ERROR); >+// defaultOptions.put(CompilerOptions.OPTION_ReportNullContractInsufficientInfo, CompilerOptions.WARNING); >+ >+// defaultOptions.put(CompilerOptions.OPTION_NullableAnnotationName, "org.eclipse.jdt.annotation.Nullable"); >+// defaultOptions.put(CompilerOptions.OPTION_NonNullAnnotationName, "org.eclipse.jdt.annotation.NonNull"); >+ } >+ return defaultOptions; >+} >+void runNegativeTestWithLibs(String[] testFiles, String expectedErrorLog) { >+ runNegativeTest( >+ testFiles, >+ expectedErrorLog, >+ this.LIBS, >+ false /*shouldFlush*/); >+} >+void runNegativeTestWithLibs(boolean shouldFlushOutputDirectory, String[] testFiles, Map customOptions, String expectedErrorLog) { >+ runNegativeTest( >+ shouldFlushOutputDirectory, >+ testFiles, >+ this.LIBS, >+ customOptions, >+ expectedErrorLog, >+ // runtime options >+ JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); >+} >+void runNegativeTestWithLibs(String[] testFiles, Map customOptions, String expectedErrorLog) { >+ runNegativeTestWithLibs(false /* flush output directory */, testFiles, customOptions, expectedErrorLog); >+} >+void runConformTestWithLibs(String[] testFiles, Map customOptions, String expectedCompilerLog) { >+ runConformTestWithLibs(false /* flush output directory */, testFiles, customOptions, expectedCompilerLog); >+} >+void runConformTestWithLibs(boolean shouldFlushOutputDirectory, String[] testFiles, Map customOptions, String expectedCompilerLog) { >+ runConformTest( >+ shouldFlushOutputDirectory, >+ testFiles, >+ this.LIBS, >+ customOptions, >+ expectedCompilerLog, >+ "",/* expected output */ >+ "",/* expected error */ >+ JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); >+} >+void runConformTest(String[] testFiles, Map customOptions, String expectedOutputString) { >+ runConformTest( >+ testFiles, >+ expectedOutputString, >+ null /*classLibraries*/, >+ true /*shouldFlushOutputDirectory*/, >+ null /*vmArguments*/, >+ customOptions, >+ null /*customRequestor*/); >+ >+} >+// a nullable argument is dereferenced without a check >+public void test_nullable_paramter_001() { >+ runNegativeTest( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " void foo(@Nullable Object o) {\n" + >+ " System.out.print(o.toString());\n" + >+ " }\n" + >+ "}\n"}, >+ "----------\n" + >+ "1. ERROR in X.java (at line 4)\n" + >+ " System.out.print(o.toString());\n" + >+ " ^\n" + >+ "Potential null pointer access: The variable o may be null at this location\n" + >+ "----------\n", >+ this.LIBS, >+ true /* shouldFlush*/); >+} >+ >+// a null value is passed to a nullable argument >+public void test_nullable_paramter_002() { >+ runConformTest( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " void foo(@Nullable Object o) {\n" + >+ " // nop\n" + >+ " }\n" + >+ " void bar() {\n" + >+ " foo(null);\n" + >+ " }\n" + >+ "}\n"}, >+ "", >+ this.LIBS, >+ false/*shouldFlush*/, >+ null/*vmArgs*/); >+} >+ >+// a non-null argument is checked for null >+public void test_nonnull_parameter_001() { >+ runNegativeTest( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " void foo(@NonNull Object o) {\n" + >+ " if (o != null)\n" + >+ " System.out.print(o.toString());\n" + >+ " }\n" + >+ "}\n"}, >+ "----------\n" + >+ "1. ERROR in X.java (at line 4)\n" + >+ " if (o != null)\n" + >+ " ^\n" + >+ "Redundant null check: The variable o cannot be null at this location\n" + >+ "----------\n", >+ this.LIBS, >+ true /* shouldFlush*/); >+} >+// a non-null argument is dereferenced without a check >+public void test_nonnull_parameter_002() { >+ runConformTest( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " void foo(@NonNull Object o) {\n" + >+ " System.out.print(o.toString());\n" + >+ " }\n" + >+ " public static void main(String... args) {\n" + >+ " new X().foo(\"OK\");\n" + >+ " }\n" + >+ "}\n"}, >+ "OK", >+ this.LIBS, >+ false/*shouldFlush*/, >+ null/*vmArgs*/); >+} >+// passing null to nonnull parameter - many fields in enclosing class >+public void test_nonnull_parameter_003() { >+ runNegativeTest( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " int i00, i01, i02, i03, i04, i05, i06, i07, i08, i09;" + >+ " int i10, i11, i12, i13, i14, i15, i16, i17, i18, i19;" + >+ " int i20, i21, i22, i23, i24, i25, i26, i27, i28, i29;" + >+ " int i30, i31, i32, i33, i34, i35, i36, i37, i38, i39;" + >+ " int i40, i41, i42, i43, i44, i45, i46, i47, i48, i49;" + >+ " int i50, i51, i52, i53, i54, i55, i56, i57, i58, i59;" + >+ " int i60, i61, i62, i63, i64, i65, i66, i67, i68, i69;" + >+ " void foo(@NonNull Object o) {\n" + >+ " System.out.print(o.toString());\n" + >+ " }\n" + >+ " void bar() {\n" + >+ " foo(null);\n" + >+ " }\n" + >+ "}\n"}, >+ "----------\n" + >+ "1. ERROR in X.java (at line 7)\n" + >+ " foo(null);\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + >+ "----------\n", >+ this.LIBS, >+ true /* shouldFlush*/); >+} >+// passing potential null to nonnull parameter - target method is consumed from .class >+public void test_nonnull_parameter_004() { >+ runConformTestWithLibs( >+ new String[] { >+ "Lib.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class Lib {\n" + >+ " void setObject(@NonNull Object o) { }\n" + >+ "}\n" >+ }, >+ null /*customOptions*/, >+ ""); >+ runNegativeTestWithLibs( >+ false, // don't flush >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " void bar(Lib l, boolean b) {\n" + >+ " Object o = null;\n" + >+ " if (b) o = new Object();\n" + >+ " l.setObject(o);\n" + >+ " }\n" + >+ "}\n"}, >+ null /*customOptions*/, >+ "----------\n" + >+ "1. ERROR in X.java (at line 5)\n" + >+ " l.setObject(o);\n" + >+ " ^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value can be null\n" + >+ "----------\n"); >+} >+// passing unknown value to nonnull parameter - target method is consumed from .class >+public void test_nonnull_parameter_005() { >+ runConformTestWithLibs( >+ new String[] { >+ "Lib.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class Lib {\n" + >+ " void setObject(@NonNull Object o) { }\n" + >+ "}\n" >+ }, >+ null /*customOptions*/, >+ ""); >+ runConformTestWithLibs( >+ false, // don't flush >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " void bar(Lib l, Object o) {\n" + >+ " l.setObject(o);\n" + >+ " }\n" + >+ "}\n"}, >+ null /* options */, >+ "----------\n" + >+ "1. WARNING in X.java (at line 3)\n" + >+ " l.setObject(o);\n" + >+ " ^\n" + >+ "Potential type mismatch: required \'@NonNull Object\' but nullness of the provided value is unknown\n" + >+ "----------\n"); >+} >+// a ternary non-null expression is passed to a nonnull parameter >+public void test_nonnull_parameter_006() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO, JavaCore.ERROR); >+ runConformTestWithLibs( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " void m1(@NonNull String a) {}\n" + >+ " void m2(@Nullable String b) {\n" + >+ " m1(b == null ? \"\" : b);\n" + >+ " }\n" + >+ "}\n"}, >+ customOptions, >+ "" /* compiler output */); >+} >+// nullable value passed to a non-null parameter in a super-call >+public void test_nonnull_parameter_007() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO, JavaCore.ERROR); >+ runNegativeTestWithLibs( >+ new String[] { >+ "XSub.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class XSub extends XSuper {\n" + >+ " XSub(@Nullable String b) {\n" + >+ " super(b);\n" + >+ " }\n" + >+ "}\n", >+ "XSuper.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class XSuper {\n" + >+ " XSuper(@NonNull String b) {\n" + >+ " }\n" + >+ "}\n" >+ }, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in XSub.java (at line 4)\n" + >+ " super(b);\n" + >+ " ^\n" + >+ "Type mismatch: required \'@NonNull String\' but the provided value can be null\n" + >+ "----------\n"); >+} >+// a nullable value is passed to a non-null parameter in an allocation expression >+public void test_nonnull_parameter_008() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO, JavaCore.ERROR); >+ runNegativeTestWithLibs( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " X(@NonNull String a) {}\n" + >+ " static X create(@Nullable String b) {\n" + >+ " return new X(b);\n" + >+ " }\n" + >+ "}\n"}, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in X.java (at line 5)\n" + >+ " return new X(b);\n" + >+ " ^\n" + >+ "Type mismatch: required \'@NonNull String\' but the provided value can be null\n" + >+ "----------\n" /* compiler output */); >+} >+// a nullable value is passed to a non-null parameter in a qualified allocation expression >+public void test_nonnull_parameter_009() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO, JavaCore.ERROR); >+ runNegativeTestWithLibs( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " class Local {\n" + >+ " Local(@NonNull String a) {}\n" + >+ " }\n" + >+ " Local create(@Nullable String b) {\n" + >+ " return this.new Local(b);\n" + >+ " }\n" + >+ "}\n"}, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in X.java (at line 7)\n" + >+ " return this.new Local(b);\n" + >+ " ^\n" + >+ "Type mismatch: required \'@NonNull String\' but the provided value can be null\n" + >+ "----------\n" /* compiler output */); >+} >+// null is passed to a non-null parameter in a qualified allocation expression, across CUs >+public void test_nonnull_parameter_010() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO, JavaCore.ERROR); >+ runNegativeTestWithLibs( >+ new String[] { >+ "ContainingInner2.java", >+ "public class ContainingInner2 {\n" + >+ " public ContainingInner2 (@org.eclipse.jdt.annotation.NonNull Object o) {\n" + >+ " }\n" + >+ " public class Inner {\n" + >+ " public Inner (@org.eclipse.jdt.annotation.NonNull Object o) {\n" + >+ " }\n" + >+ " }\n" + >+ "}\n", >+ "X.java", >+ "public class X {\n" + >+ " void create() {\n" + >+ " ContainingInner2 container = new ContainingInner2(null);\n" + >+ " ContainingInner2.Inner inner = container.new Inner(null);\n" + >+ " }\n" + >+ "}\n"}, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in X.java (at line 3)\n" + >+ " ContainingInner2 container = new ContainingInner2(null);\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 4)\n" + >+ " ContainingInner2.Inner inner = container.new Inner(null);\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + >+ "----------\n" /* compiler output */); >+} >+// null is passed to a non-null parameter in a qualified allocation expression, target class read from .class >+public void test_nonnull_parameter_011() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO, JavaCore.ERROR); >+ runConformTestWithLibs( >+ new String[] { >+ "ContainingInner2.java", >+ "public class ContainingInner2 {\n" + >+ " public ContainingInner2 (@org.eclipse.jdt.annotation.NonNull Object o) {\n" + >+ " }\n" + >+ " public class Inner {\n" + >+ " public Inner (@org.eclipse.jdt.annotation.NonNull Object o) {\n" + >+ " }\n" + >+ " }\n" + >+ "}\n", >+ }, >+ null /*customOptions*/, >+ ""); >+ runNegativeTestWithLibs( >+ false, // flush directory >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " void create() {\n" + >+ " ContainingInner2 container = new ContainingInner2(null);\n" + >+ " ContainingInner2.Inner inner = container.new Inner(null);\n" + >+ " }\n" + >+ "}\n"}, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in X.java (at line 3)\n" + >+ " ContainingInner2 container = new ContainingInner2(null);\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 4)\n" + >+ " ContainingInner2.Inner inner = container.new Inner(null);\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + >+ "----------\n" /* compiler output */); >+} >+// null is passed to a non-null parameter in a qualified allocation expression, generic constructor, target class read from .class >+public void test_nonnull_parameter_012() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO, JavaCore.ERROR); >+ runConformTestWithLibs( >+ new String[] { >+ "ContainingInner2.java", >+ "public class ContainingInner2 {\n" + >+ " public ContainingInner2 (@org.eclipse.jdt.annotation.NonNull Object o) {\n" + >+ " }\n" + >+ " public class Inner {\n" + >+ " public <T> Inner (@org.eclipse.jdt.annotation.NonNull T o) {\n" + >+ " }\n" + >+ " }\n" + >+ "}\n", >+ }, >+ null /*customOptions*/, >+ ""); >+ runNegativeTestWithLibs( >+ false, // flush directory >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " void create() {\n" + >+ " ContainingInner2 container = new ContainingInner2(null);\n" + >+ " ContainingInner2.Inner inner = container.new Inner(null);\n" + >+ " }\n" + >+ "}\n"}, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in X.java (at line 3)\n" + >+ " ContainingInner2 container = new ContainingInner2(null);\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 4)\n" + >+ " ContainingInner2.Inner inner = container.new Inner(null);\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + >+ "----------\n" /* compiler output */); >+} >+// a method of a local class has a non-null parameter, client passes null >+public void test_nonnull_parameter_013() { >+ runNegativeTestWithLibs( >+ new String[] { >+ "B.java", >+ "class B {\n" + >+ " void bar () {\n" + >+ " class Local {\n" + >+ " void callMe(@org.eclipse.jdt.annotation.NonNull Object o){\n" + >+ " }\n" + >+ " }\n" + >+ " Local l = new Local();\n" + >+ " l.callMe(null);\n" + >+ " } \n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in B.java (at line 8)\n" + >+ " l.callMe(null);\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + >+ "----------\n"); >+} >+// non-null varargs (message send) >+public void test_nonnull_parameter_015() { >+ if (this.complianceLevel > ClassFileConstants.JDK1_7) { >+ fail("Reminder: should check if JSR 308 mandates a change in handling vararg elements (see bug 365983)."); >+ return; >+ } >+ runNegativeTest( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " void foo(@NonNull Object ... o) {\n" + >+ " if (o != null)\n" + >+ " System.out.print(o.toString());\n" + >+ " }\n" + >+ " void foo2(int i, @NonNull Object ... o) {\n" + >+ " if (o.length > 0 && o[0] != null)\n" + >+ " System.out.print(o[0].toString());\n" + >+ " }\n" + >+ " void bar() {\n" + >+ " foo((Object)null);\n" + // unchecked: single plain argument >+ " Object[] objs = null;\n" + >+ " foo(objs);\n" + // error >+ " foo(this, null);\n" + // unchecked: multiple plain arguments >+ " foo2(2, (Object)null);\n" + // unchecked: single plain argument >+ " foo2(2, null, this);\n" + // unchecked: multiple plain arguments >+ " foo2(2, null);\n" + // error >+ " }\n" + >+ "}\n"}, >+ "----------\n" + >+ "1. ERROR in X.java (at line 4)\n" + >+ " if (o != null)\n" + >+ " ^\n" + >+ "Redundant null check: The variable o cannot be null at this location\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 14)\n" + >+ " foo(objs);\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull Object[]\' but the provided value is null\n" + >+ "----------\n" + >+ "3. WARNING in X.java (at line 18)\n" + >+ " foo2(2, null);\n" + >+ " ^^^^^^^^^^^^^\n" + >+ "The argument of type null should explicitly be cast to Object[] for the invocation of the varargs method foo2(int, Object...) from type X. It could alternatively be cast to Object for a varargs invocation\n" + >+ "----------\n" + >+ "4. ERROR in X.java (at line 18)\n" + >+ " foo2(2, null);\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull Object[]\' but the provided value is null\n" + >+ "----------\n", >+ this.LIBS, >+ true /* shouldFlush*/); >+} >+// non-null varargs (allocation and explicit constructor calls) >+public void test_nonnull_parameter_016() { >+ if (this.complianceLevel > ClassFileConstants.JDK1_7) { >+ fail("Reminder: should check if JSR 308 mandates a change in handling vararg elements (see bug 365983)."); >+ return; >+ } >+ runNegativeTest( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " X(@NonNull Object ... o) {\n" + >+ " if (o != null)\n" + >+ " System.out.print(o.toString());\n" + >+ " }\n" + >+ " class Y extends X {\n" + >+ " Y(int i, @NonNull Object ... o) {\n" + >+ " super(i, (Object)null);\n" + >+ " }\n" + >+ " Y(char c, @NonNull Object ... o) {\n" + >+ " this(1, new Object(), null);\n" + >+ " }\n" + >+ " }\n" + >+ " void bar() {\n" + >+ " new X((Object[])null);\n" + >+ " new X(this, null);\n" + >+ " X x = new X(null, this);\n" + >+ " x.new Y(2, (Object)null);\n" + >+ " this.new Y(2, null, this);\n" + >+ " this.new Y(2, (Object[])null);\n" + >+ " }\n" + >+ "}\n"}, >+ "----------\n" + >+ "1. ERROR in X.java (at line 4)\n" + >+ " if (o != null)\n" + >+ " ^\n" + >+ "Redundant null check: The variable o cannot be null at this location\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 16)\n" + >+ " new X((Object[])null);\n" + >+ " ^^^^^^^^^^^^^^\n" + >+ "Type mismatch: required \'@NonNull Object[]\' but the provided value is null\n" + >+ "----------\n" + >+ "3. ERROR in X.java (at line 21)\n" + >+ " this.new Y(2, (Object[])null);\n" + >+ " ^^^^^^^^^^^^^^\n" + >+ "Type mismatch: required \'@NonNull Object[]\' but the provided value is null\n" + >+ "----------\n", >+ this.LIBS, >+ true /* shouldFlush*/); >+} >+// Bug 367203 - [compiler][null] detect assigning null to nonnull argument >+public void test_nonnull_argument_001() { >+ runNegativeTestWithLibs( >+ new String[] { >+ "ShowNPE2.java", >+ "import org.eclipse.jdt.annotation.NonNullByDefault;\n" + >+ "@NonNullByDefault\n" + >+ "public class ShowNPE2 {\n" + >+ " public Object foo(Object o1, final boolean b) {\n" + >+ " o1 = null; // expect NPE error\n" + >+ " System.out.println(o1.toString()); \n" + >+ " return null; // expect NPE error\n" + >+ " }\n" + >+ "}" >+ }, >+ "----------\n" + >+ "1. ERROR in ShowNPE2.java (at line 5)\n" + >+ " o1 = null; // expect NPE error\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + >+ "----------\n" + >+ "2. ERROR in ShowNPE2.java (at line 7)\n" + >+ " return null; // expect NPE error\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + >+ "----------\n"); >+} >+// Bug 367203 - [compiler][null] detect assigning null to nonnull argument >+public void test_nonnull_argument_002() { >+ runNegativeTestWithLibs( >+ new String[] { >+ "ShowNPE2.java", >+ "import org.eclipse.jdt.annotation.NonNullByDefault;\n" + >+ "@NonNullByDefault\n" + >+ "public class ShowNPE2 {\n" + >+ " public Object foo(Object o1, final boolean b) {\n" + >+ " bar(o1); // expecting no problem\n" + >+ " return null; // expect NPE error\n" + >+ " }\n" + >+ " void bar(Object o2) {}\n" + >+ "}" >+ }, >+ "----------\n" + >+ "1. ERROR in ShowNPE2.java (at line 6)\n" + >+ " return null; // expect NPE error\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + >+ "----------\n"); >+} >+// a method of a local class has a non-null parameter, client passes potential null (msg send) >+public void test_nonnull_parameter_014() { >+ runNegativeTestWithLibs( >+ new String[] { >+ "B.java", >+ "class B {\n" + >+ " void bar () {\n" + >+ " class Local {\n" + >+ " void callMe(@org.eclipse.jdt.annotation.NonNull Object o){\n" + >+ " }\n" + >+ " }\n" + >+ " Local l = new Local();\n" + >+ " l.callMe(getNull());\n" + >+ " }\n" + >+ " @org.eclipse.jdt.annotation.Nullable Object getNull() { return null; }" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in B.java (at line 8)\n" + >+ " l.callMe(getNull());\n" + >+ " ^^^^^^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value can be null\n" + >+ "----------\n"); >+} >+// assigning potential null to a nonnull local variable >+public void test_nonnull_local_001() { >+ runNegativeTest( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " void foo(boolean b, Object p) {\n" + >+ " @NonNull Object o1 = b ? null : new Object();\n" + >+ " @NonNull String o2 = \"\";\n" + >+ " o2 = null;\n" + >+ " @NonNull Object o3 = p;\n" + >+ " }\n" + >+ "}\n"}, >+ "----------\n" + >+ "1. ERROR in X.java (at line 4)\n" + >+ " @NonNull Object o1 = b ? null : new Object();\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value can be null\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 6)\n" + >+ " o2 = null;\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull String\' but the provided value is null\n" + >+ "----------\n" + >+ "3. WARNING in X.java (at line 7)\n" + >+ " @NonNull Object o3 = p;\n" + >+ " ^\n" + >+ "Potential type mismatch: required \'@NonNull Object\' but nullness of the provided value is unknown\n" + >+ "----------\n", >+ this.LIBS, >+ true /* shouldFlush*/); >+} >+ >+// assigning potential null to a nonnull local variable - separate decl and assignment >+public void test_nonnull_local_002() { >+ runNegativeTest( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " void foo(boolean b, Object p) {\n" + >+ " @NonNull Object o1;\n" + >+ " o1 = b ? null : new Object();\n" + >+ " @NonNull String o2;\n" + >+ " o2 = \"\";\n" + >+ " o2 = null;\n" + >+ " @NonNull Object o3;\n" + >+ " o3 = p;\n" + >+ " }\n" + >+ "}\n"}, >+ "----------\n" + >+ "1. ERROR in X.java (at line 5)\n" + >+ " o1 = b ? null : new Object();\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value can be null\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 8)\n" + >+ " o2 = null;\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull String\' but the provided value is null\n" + >+ "----------\n" + >+ "3. WARNING in X.java (at line 10)\n" + >+ " o3 = p;\n" + >+ " ^\n" + >+ "Potential type mismatch: required \'@NonNull Object\' but nullness of the provided value is unknown\n" + >+ "----------\n", >+ this.LIBS, >+ true /* shouldFlush*/); >+} >+ >+// a method tries to tighten the type specification, super declares parameter o as @Nullable >+// other parameters: s is redefined from not constrained to @Nullable which is OK >+// third is redefined from not constrained to @NonNull which is bad, too >+public void test_parameter_specification_inheritance_001() { >+ runConformTestWithLibs( >+ new String[] { >+ "Lib.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class Lib {\n" + >+ " void foo(String s, @Nullable Object o, Object third) { }\n" + >+ "}\n" >+ }, >+ null /*customOptions*/, >+ ""); >+ runNegativeTestWithLibs( >+ false, // don't flush >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X extends Lib {\n" + >+ " @Override\n" + >+ " void foo(@Nullable String s, @NonNull Object o, @NonNull Object third) { System.out.print(o.toString()); }\n" + >+ "}\n" >+ }, >+ null /*customOptions*/, >+ "----------\n" + >+ "1. ERROR in X.java (at line 4)\n" + >+ " void foo(@Nullable String s, @NonNull Object o, @NonNull Object third) { System.out.print(o.toString()); }\n" + >+ " ^^^^^^^^^^^^^^^\n" + >+ "Illegal redefinition of parameter o, inherited method from Lib declares this parameter as @Nullable\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 4)\n" + >+ " void foo(@Nullable String s, @NonNull Object o, @NonNull Object third) { System.out.print(o.toString()); }\n" + >+ " ^^^^^^^^^^^^^^^\n" + >+ "Illegal redefinition of parameter third, inherited method from Lib does not constrain this parameter\n" + >+ "----------\n"); >+} >+// a method body fails to redeclare the inherited null annotation, super declares parameter as @Nullable >+public void test_parameter_specification_inheritance_002() { >+ runConformTest( >+ new String[] { >+ "Lib.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class Lib {\n" + >+ " void foo(@Nullable Object o) { }\n" + >+ "}\n" >+ }, >+ "", >+ this.LIBS, >+ false/*shouldFlush*/, >+ null/*vmArgs*/); >+ runNegativeTestWithLibs( >+ false, // don't flush >+ new String[] { >+ "X.java", >+ "public class X extends Lib {\n" + >+ " @Override\n" + >+ " void foo(Object o) {\n" + >+ " System.out.print(o.toString());\n" + >+ " }\n" + >+ "}\n" >+ }, >+ null /*customOptions*/, >+ "----------\n" + >+ "1. ERROR in X.java (at line 3)\n" + >+ " void foo(Object o) {\n" + >+ " ^^^^^^\n" + >+ "Missing nullable annotation: inherited method from Lib declares this parameter as @Nullable\n" + >+ "----------\n"); >+} >+// a method relaxes the parameter null specification, super interface declares parameter o as @NonNull >+// other (first) parameter just repeats the inherited @NonNull >+public void test_parameter_specification_inheritance_003() { >+ runConformTest( >+ new String[] { >+ "IX.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public interface IX {\n" + >+ " void foo(@NonNull String s, @NonNull Object o);\n" + >+ "}\n", >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X implements IX {\n" + >+ " public void foo(@NonNull String s, @Nullable Object o) { ; }\n" + >+ " void bar() { foo(\"OK\", null); }\n" + >+ "}\n" >+ }, >+ "", >+ this.LIBS, >+ false/*shouldFlush*/, >+ null/*vmArgs*/); >+} >+// a method adds a @NonNull annotation, super interface has no null annotation >+// changing other from unconstrained to @Nullable is OK >+public void test_parameter_specification_inheritance_004() { >+ runConformTest( >+ new String[] { >+ "IX.java", >+ "public interface IX {\n" + >+ " void foo(Object o, Object other);\n" + >+ "}\n" >+ }); >+ runNegativeTestWithLibs( >+ false, // don't flush >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X implements IX {\n" + >+ " public void foo(@NonNull Object o, @Nullable Object other) { System.out.print(o.toString()); }\n" + >+ "}\n" >+ }, >+ null /*customOptions*/, >+ "----------\n" + >+ "1. ERROR in X.java (at line 3)\n" + >+ " public void foo(@NonNull Object o, @Nullable Object other) { System.out.print(o.toString()); }\n" + >+ " ^^^^^^^^^^^^^^^\n" + >+ "Illegal redefinition of parameter o, inherited method from IX does not constrain this parameter\n" + >+ "----------\n"); >+} >+// a method tries to relax the null contract, super declares @NonNull return >+public void test_parameter_specification_inheritance_005() { >+ runConformTestWithLibs( >+ new String[] { >+ "Lib.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class Lib {\n" + >+ " @NonNull Object getObject() { return new Object(); }\n" + >+ "}\n" >+ }, >+ null /*customOptions*/, >+ ""); >+ runNegativeTestWithLibs( >+ false, //dont' flush >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X extends Lib {\n" + >+ " @Override\n" + >+ " @Nullable Object getObject() { return null; }\n" + >+ "}\n" >+ }, >+ null /*customOptions*/, >+ "----------\n" + >+ "1. ERROR in X.java (at line 4)\n" + >+ " @Nullable Object getObject() { return null; }\n" + >+ " ^^^^^^^^^^^^^^^^\n" + >+ "The return type is incompatible with the @NonNull return from Lib.getObject()\n" + >+ "----------\n"); >+} >+ >+// super has no constraint for return, sub method confirms the null contract as @Nullable >+public void test_parameter_specification_inheritance_006() { >+ runConformTest( >+ new String[] { >+ "Lib.java", >+ "public class Lib {\n" + >+ " Object getObject() { return null; }\n" + >+ "}\n" >+ }); >+ runConformTestWithLibs( >+ false, // don't flush >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X extends Lib {\n" + >+ " @Override\n" + >+ " @Nullable Object getObject() { return null; }\n" + >+ "}\n" >+ }, >+ null /*customOptions*/, >+ ""); >+} >+// a method body violates the inherited null specification, super declares @NonNull return, missing redeclaration >+public void test_parameter_specification_inheritance_007() { >+ runConformTestWithLibs( >+ new String[] { >+ "Lib.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class Lib {\n" + >+ " @NonNull Object getObject() { return new Object(); }\n" + >+ "}\n" >+ }, >+ null /*customOptions*/, >+ ""); >+ runNegativeTestWithLibs( >+ false, // don't flush >+ new String[] { >+ "X.java", >+ "public class X extends Lib {\n" + >+ " @Override\n" + >+ " Object getObject() { return null; }\n" + >+ "}\n" >+ }, >+ null /*customOptions*/, >+ "----------\n" + >+ "1. ERROR in X.java (at line 3)\n" + >+ " Object getObject() { return null; }\n" + >+ " ^^^^^^\n" + >+ "The return type is incompatible with the @NonNull return from Lib.getObject()\n" + >+ "----------\n"); >+} >+//a method body violates the @NonNull return specification (repeated from super) >+public void test_parameter_specification_inheritance_007a() { >+ runConformTestWithLibs( >+ new String[] { >+ "Lib.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class Lib {\n" + >+ " @NonNull Object getObject() { return new Object(); }\n" + >+ "}\n" >+ }, >+ null /*customOptions*/, >+ ""); >+ runNegativeTestWithLibs( >+ false, // don't flush >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X extends Lib {\n" + >+ " @Override\n" + >+ " @NonNull Object getObject() { return null; }\n" + >+ "}\n" >+ }, >+ null /*customOptions*/, >+ "----------\n" + >+ "1. ERROR in X.java (at line 4)\n" + >+ " @NonNull Object getObject() { return null; }\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + >+ "----------\n"); >+} >+// a client potentially violates the inherited null specification, super interface declares @NonNull parameter >+public void test_parameter_specification_inheritance_008() { >+ Map options = getCompilerOptions(); >+ options.put(JavaCore.COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO, JavaCore.ERROR); >+ runConformTestWithLibs( >+ new String[] { >+ "IX.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public interface IX {\n" + >+ " void printObject(@NonNull Object o);\n" + >+ "}\n" >+ }, >+ null /*customOptions*/, >+ ""); >+ runNegativeTestWithLibs( >+ false, // don't flush >+ new String[] { >+ "X.java", >+ "public class X implements IX {\n" + >+ " public void printObject(Object o) { System.out.print(o.toString()); }\n" + >+ "}\n", >+ "M.java", >+ "public class M{\n" + >+ " void foo(IX x, Object o) {\n" + >+ " x.printObject(o);\n" + >+ " }\n" + >+ "}\n" >+ }, >+ options, >+ "----------\n" + >+ // additional error: >+ "1. ERROR in X.java (at line 2)\n" + >+ " public void printObject(Object o) { System.out.print(o.toString()); }\n" + >+ " ^^^^^^\n" + >+ "Missing non-null annotation: inherited method from IX declares this parameter as @NonNull\n" + >+ "----------\n" + >+ // main error: >+ "----------\n" + >+ "1. ERROR in M.java (at line 3)\n" + >+ " x.printObject(o);\n" + >+ " ^\n" + >+ "Potential type mismatch: required \'@NonNull Object\' but nullness of the provided value is unknown\n" + >+ "----------\n"); >+} >+// a static method has a more relaxed null contract than a like method in the super class, but no overriding. >+public void test_parameter_specification_inheritance_009() { >+ runConformTestWithLibs( >+ new String[] { >+ "Lib.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class Lib {\n" + >+ " @NonNull static Object getObject() { return new Object(); }\n" + >+ "}\n", >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X extends Lib {\n" + >+ " @Nullable static Object getObject() { return null; }\n" + >+ "}\n" >+ }, >+ null /*customOptions*/, >+ ""); >+} >+// class default is nonnull, method and its super both use the default >+public void test_parameter_specification_inheritance_010() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO, JavaCore.ERROR); >+ runConformTestWithLibs( >+ new String[] { >+ "p1/X.java", >+ "package p1;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@NonNullByDefault\n" + >+ "public class X {\n" + >+ " protected String getString(String s) {\n" + >+ " if (Character.isLowerCase(s.charAt(0)))\n" + >+ " return getString(s);\n" + >+ " return s;\n" + >+ " }\n" + >+ "}\n", >+ "p1/Y.java", >+ "package p1;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@NonNullByDefault\n" + >+ "public class Y extends X {\n" + >+ " @Override\n" + >+ " protected String getString(String s) {\n" + >+ " return super.getString(s);\n" + >+ " }\n" + >+ "}\n", >+ }, >+ customOptions, >+ ""); >+} >+// class default is nonnull, method and its super both use the default, super-call passes null >+public void test_parameter_specification_inheritance_011() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO, JavaCore.ERROR); >+ runNegativeTestWithLibs( >+ new String[] { >+ "p1/X.java", >+ "package p1;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@NonNullByDefault\n" + >+ "public class X {\n" + >+ " protected String getString(String s) {\n" + >+ " if (Character.isLowerCase(s.charAt(0)))\n" + >+ " return getString(s);\n" + >+ " return s;\n" + >+ " }\n" + >+ "}\n", >+ "p1/Y.java", >+ "package p1;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@NonNullByDefault\n" + >+ "public class Y extends X {\n" + >+ " @Override\n" + >+ " protected String getString(String s) {\n" + >+ " return super.getString(null);\n" + >+ " }\n" + >+ "}\n", >+ }, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in p1\\Y.java (at line 7)\n" + >+ " return super.getString(null);\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull String\' but the provided value is null\n" + >+ "----------\n"); >+} >+// methods from two super types have different null contracts. >+// sub-class merges both using the weakest common contract >+public void test_parameter_specification_inheritance_012() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO, JavaCore.ERROR); >+ runConformTestWithLibs( >+ new String[] { >+ "p1/X.java", >+ "package p1;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " public @Nullable String getString(String s1, @Nullable String s2, @NonNull String s3) {\n" + >+ " return s1;\n" + >+ " }\n" + >+ "}\n", >+ "p1/IY.java", >+ "package p1;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public interface IY {\n" + >+ " @NonNull String getString(@NonNull String s1, @NonNull String s2, @Nullable String s3);\n" + >+ "}\n", >+ "p1/Y.java", >+ "package p1;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class Y extends X implements IY {\n" + >+ " @Override\n" + >+ " public @NonNull String getString(@Nullable String s1, @Nullable String s2, @Nullable String s3) {\n" + >+ " return \"\";\n" + >+ " }\n" + >+ "}\n", >+ }, >+ customOptions, >+ ""); >+} >+// methods from two super types have different null contracts. >+// sub-class overrides this method in non-conforming ways >+public void test_parameter_specification_inheritance_013() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO, JavaCore.ERROR); >+ runNegativeTestWithLibs( >+ new String[] { >+ "p1/X.java", >+ "package p1;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " public @Nullable String getString(String s1, @Nullable String s2, @NonNull String s3) {\n" + >+ " return s1;\n" + >+ " }\n" + >+ "}\n", >+ "p1/IY.java", >+ "package p1;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public interface IY {\n" + >+ " @NonNull String getString(@NonNull String s1, @NonNull String s2, @Nullable String s3);\n" + >+ "}\n", >+ "p1/Y.java", >+ "package p1;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class Y extends X implements IY {\n" + >+ " @Override\n" + >+ " public @Nullable String getString(String s1, @NonNull String s2, @NonNull String s3) {\n" + >+ " return \"\";\n" + >+ " }\n" + >+ "}\n", >+ }, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in p1\\Y.java (at line 5)\n" + >+ " public @Nullable String getString(String s1, @NonNull String s2, @NonNull String s3) {\n" + >+ " ^^^^^^^^^^^^^^^^\n" + >+ "The return type is incompatible with the @NonNull return from IY.getString(String, String, String)\n" + >+ "----------\n" + >+ "2. ERROR in p1\\Y.java (at line 5)\n" + >+ " public @Nullable String getString(String s1, @NonNull String s2, @NonNull String s3) {\n" + >+ " ^^^^^^\n" + >+ "Missing non-null annotation: inherited method from IY declares this parameter as @NonNull\n" + >+ "----------\n" + >+ "3. ERROR in p1\\Y.java (at line 5)\n" + >+ " public @Nullable String getString(String s1, @NonNull String s2, @NonNull String s3) {\n" + >+ " ^^^^^^^^^^^^^^^\n" + >+ "Illegal redefinition of parameter s2, inherited method from X declares this parameter as @Nullable\n" + >+ "----------\n" + >+ "4. ERROR in p1\\Y.java (at line 5)\n" + >+ " public @Nullable String getString(String s1, @NonNull String s2, @NonNull String s3) {\n" + >+ " ^^^^^^^^^^^^^^^\n" + >+ "Illegal redefinition of parameter s3, inherited method from IY declares this parameter as @Nullable\n" + >+ "----------\n"); >+} >+// methods from two super types have different null contracts. >+// sub-class does not override, but should to bridge the incompatibility >+public void test_parameter_specification_inheritance_014() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO, JavaCore.ERROR); >+ runNegativeTestWithLibs( >+ new String[] { >+ "p1/IY.java", >+ "package p1;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public interface IY {\n" + >+ " public @NonNull String getString1(String s);\n" + >+ " public @NonNull String getString2(String s);\n" + >+ " public String getString3(@Nullable String s);\n" + >+ " public @NonNull String getString4(@Nullable String s);\n" + >+ " public @NonNull String getString5(@Nullable String s);\n" + >+ " public @Nullable String getString6(@NonNull String s);\n" + >+ "}\n", >+ "p1/X.java", >+ "package p1;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " public @Nullable String getString1(String s) {\n" + // incomp. return >+ " return s;\n" + >+ " }\n" + >+ " public String getString2(String s) {\n" + // incomp. return >+ " return s;\n" + >+ " }\n" + >+ " public String getString3(String s) {\n" + // incomp. arg >+ " return \"\";\n" + >+ " }\n" + >+ " public @NonNull String getString4(@Nullable String s) {\n" + >+ " return \"\";\n" + >+ " }\n" + >+ " public @NonNull String getString5(@NonNull String s) {\n" + // incomp. arg >+ " return s;\n" + >+ " }\n" + >+ " public @NonNull String getString6(@Nullable String s) {\n" + >+ " return \"\";\n" + >+ " }\n" + >+ "}\n", >+ "p1/Y.java", >+ "package p1;\n" + >+ "public class Y extends X implements IY {\n" + >+ "}\n", >+ }, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in p1\\Y.java (at line 2)\n" + >+ " public class Y extends X implements IY {\n" + >+ " ^\n" + >+ "The method getString1(String) from X cannot implement the corresponding method from IY due to incompatible nullness constraints\n" + >+ "----------\n" + >+ "2. ERROR in p1\\Y.java (at line 2)\n" + >+ " public class Y extends X implements IY {\n" + >+ " ^\n" + >+ "The method getString2(String) from X cannot implement the corresponding method from IY due to incompatible nullness constraints\n" + >+ "----------\n" + >+ "3. ERROR in p1\\Y.java (at line 2)\n" + >+ " public class Y extends X implements IY {\n" + >+ " ^\n" + >+ "The method getString5(String) from X cannot implement the corresponding method from IY due to incompatible nullness constraints\n" + >+ "----------\n" + >+ "4. ERROR in p1\\Y.java (at line 2)\n" + >+ " public class Y extends X implements IY {\n" + >+ " ^\n" + >+ "The method getString3(String) from X cannot implement the corresponding method from IY due to incompatible nullness constraints\n" + >+ "----------\n"); >+} >+// a nullable return value is dereferenced without a check >+public void test_nullable_return_001() { >+ runNegativeTestWithLibs( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " @Nullable Object getObject() { return null; }\n" + >+ " void foo() {\n" + >+ " Object o = getObject();\n" + >+ " System.out.print(o.toString());\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 6)\n" + >+ " System.out.print(o.toString());\n" + >+ " ^\n" + >+ "Potential null pointer access: The variable o may be null at this location\n" + >+ "----------\n"); >+} >+// a nullable return value is dereferenced without a check, method is read from .class file >+public void test_nullable_return_002() { >+ runConformTestWithLibs( >+ new String[] { >+ "Lib.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class Lib {\n" + >+ " @Nullable Object getObject() { return null; }\n" + >+ "}\n" >+ }, >+ null /*customOptions*/, >+ ""); >+ runNegativeTestWithLibs( >+ false, // don't flush >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " void foo(Lib l) {\n" + >+ " Object o = l.getObject();\n" + >+ " System.out.print(o.toString());\n" + >+ " }\n" + >+ "}\n" >+ }, >+ null /*customOptions*/, >+ "----------\n" + >+ "1. ERROR in X.java (at line 4)\n" + >+ " System.out.print(o.toString());\n" + >+ " ^\n" + >+ "Potential null pointer access: The variable o may be null at this location\n" + >+ "----------\n"); >+} >+// a non-null return value is checked for null, method is read from .class file >+public void test_nonnull_return_001() { >+ runConformTestWithLibs( >+ new String[] { >+ "Lib.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class Lib {\n" + >+ " @NonNull Object getObject() { return new Object(); }\n" + >+ "}\n" >+ }, >+ null /*customOptions*/, >+ ""); >+ runNegativeTestWithLibs( >+ false, // don't flush >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " void foo(Lib l) {\n" + >+ " Object o = l.getObject();\n" + >+ " if (o != null)\n" + >+ " System.out.print(o.toString());\n" + >+ " }\n" + >+ "}\n" >+ }, >+ null /*customOptions*/, >+ "----------\n" + >+ "1. ERROR in X.java (at line 4)\n" + >+ " if (o != null)\n" + >+ " ^\n" + >+ "Redundant null check: The variable o cannot be null at this location\n" + >+ "----------\n"); >+} >+// a non-null method returns null >+public void test_nonnull_return_003() { >+ runNegativeTestWithLibs( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " @NonNull Object getObject(boolean b) {\n" + >+ " if (b)\n" + >+ " return null;\n" + // definite specification violation despite enclosing "if" >+ " return new Object();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 5)\n" + >+ " return null;\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + >+ "----------\n"); >+} >+// a non-null method potentially returns null >+public void test_nonnull_return_004() { >+ runNegativeTestWithLibs( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " @NonNull Object getObject(@Nullable Object o) {\n" + >+ " return o;\n" + // 'o' is only potentially null >+ " }\n" + >+ "}\n" >+ }, >+ null /*customOptions*/, >+ "----------\n" + >+ "1. ERROR in X.java (at line 4)\n" + >+ " return o;\n" + >+ " ^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value can be null\n" + >+ "----------\n"); >+} >+// a non-null method returns its non-null argument >+public void test_nonnull_return_005() { >+ runConformTestWithLibs( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " @NonNull Object getObject(@NonNull Object o) {\n" + >+ " return o;\n" + >+ " }\n" + >+ "}\n" >+ }, >+ null, // options >+ ""); >+} >+//a non-null method has insufficient nullness info for its return value >+public void test_nonnull_return_006() { >+ runNegativeTestWithLibs( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " @NonNull Object getObject(Object o) {\n" + >+ " return o;\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. WARNING in X.java (at line 4)\n" + >+ " return o;\n" + >+ " ^\n" + >+ "Potential type mismatch: required \'@NonNull Object\' but nullness of the provided value is unknown\n" + >+ "----------\n"); >+} >+// a result from a nullable method is directly dereferenced >+public void test_nonnull_return_007() { >+ runNegativeTestWithLibs( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " @Nullable Object getObject() {\n" + >+ " return null;\n" + >+ " }\n" + >+ " void test() {\n" + >+ " getObject().toString();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 7)\n" + >+ " getObject().toString();\n" + >+ " ^^^^^^^^^^^\n" + >+ "Potential null pointer access: The method getObject() may return null\n" + >+ "----------\n"); >+} >+// a result from a nonnull method is directly checked for null: redundant >+public void test_nonnull_return_008() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK, JavaCore.ERROR); >+ runNegativeTestWithLibs( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " @NonNull Object getObject() {\n" + >+ " return new Object();\n" + >+ " }\n" + >+ " void test() {\n" + >+ " if (getObject() == null)\n" + >+ " throw new RuntimeException();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in X.java (at line 7)\n" + >+ " if (getObject() == null)\n" + >+ " ^^^^^^^^^^^\n" + >+ "Redundant null check: The method getObject() cannot return null\n" + >+ "----------\n"); >+} >+// a result from a nonnull method is directly checked for null (from local): redundant >+public void test_nonnull_return_009() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK, JavaCore.ERROR); >+ runNegativeTestWithLibs( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " @NonNull Object getObject() {\n" + >+ " return new Object();\n" + >+ " }\n" + >+ " void test() {\n" + >+ " Object left = null;\n" + >+ " if (left != getObject())\n" + >+ " throw new RuntimeException();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in X.java (at line 8)\n" + >+ " if (left != getObject())\n" + >+ " ^^^^\n" + >+ "Redundant null check: The variable left can only be null at this location\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 8)\n" + >+ " if (left != getObject())\n" + >+ " ^^^^^^^^^^^\n" + >+ "Redundant null check: The method getObject() cannot return null\n" + >+ "----------\n"); >+} >+// a result from a nonnull method is directly checked for null (from local): not redundant due to loop >+public void test_nonnull_return_009a() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK, JavaCore.ERROR); >+ runConformTestWithLibs( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " @NonNull Object getObject() {\n" + >+ " return new Object();\n" + >+ " }\n" + >+ " void test() {\n" + >+ " Object left = null;\n" + >+ " for (int i=0; i<3; i++) {\n" + >+ " if (left != getObject())\n" + >+ " throw new RuntimeException();\n" + >+ " left = new Object();\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ customOptions, >+ ""); >+} >+// a result from a nonnull method is directly checked for null (from local): redundant despite loop >+// disabled because only one of two desirable errors is raised >+// need to integrate @NonNull expressions (MessageSend and more) into deferred analysis by FlowContext >+public void _test_nonnull_return_009b() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK, JavaCore.ERROR); >+ runConformTestWithLibs( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " @NonNull Object getObject() {\n" + >+ " return new Object();\n" + >+ " }\n" + >+ " void test() {\n" + >+ " Object left = null;\n" + >+ " for (int i=0; i<3; i++) {\n" + >+ " if (left != getObject())\n" + >+ " throw new RuntimeException();\n" + >+ " // left remains null\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in X.java (at line 9)\n" + >+ " if (left != getObject())\n" + >+ " ^^^^\n" + >+ "Redundant null check: The variable left can only be null at this location\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 9)\n" + >+ " if (left != getObject())\n" + >+ " ^^^^^^^^^^^\n" + >+ "Redundant null check: The method getObject() cannot return null\n" + >+ "----------\n"); >+} >+// a result from a nullable method is assigned and checked for null (from local): not redundant >+// see also Bug 336428 - [compiler][null] bogus warning "redundant null check" in condition of do {} while() loop >+public void test_nonnull_return_010() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK, JavaCore.ERROR); >+ runNegativeTestWithLibs( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " @Nullable X getX() {\n" + >+ " return new X();\n" + >+ " }\n" + >+ " void test() {\n" + >+ " X left = this;\n" + >+ " do {\n" + >+ " if (left == null) \n" + >+ " throw new RuntimeException();\n" + >+ " } while ((left = left.getX()) != null);\n" + // no warning/error here! >+ " }\n" + >+ "}\n" >+ }, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in X.java (at line 9)\n" + >+ " if (left == null) \n" + >+ " ^^^^\n" + >+ "Null comparison always yields false: The variable left cannot be null at this location\n" + >+ "----------\n"); >+} >+// a non-null method returns a checked-for null value, but that branch is dead code >+public void test_nonnull_return_011() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO, JavaCore.ERROR); >+ runNegativeTestWithLibs( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@NonNullByDefault\n" + >+ "public class X {\n" + >+ " Object getObject(Object dubious) {\n" + >+ " if (dubious == null)\n" + // redundant >+ " return dubious;\n" + // definitely null, but not reported inside dead code >+ " return new Object();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in X.java (at line 5)\n" + >+ " if (dubious == null)\n" + >+ " ^^^^^^^\n" + >+ "Null comparison always yields false: The variable dubious cannot be null at this location\n" + >+ "----------\n" + >+ "2. WARNING in X.java (at line 6)\n" + >+ " return dubious;\n" + >+ " ^^^^^^^^^^^^^^^\n" + >+ "Dead code\n" + >+ "----------\n"); >+} >+// a non-null method returns a definite null from a conditional expression >+// requires the fix for Bug 354554 - [null] conditional with redundant condition yields weak error message >+// TODO(SH): ENABLE! >+public void _test_nonnull_return_012() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO, JavaCore.ERROR); >+ runNegativeTestWithLibs( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@NonNullByDefault\n" + >+ "public class X {\n" + >+ " Object getObject(Object dubious) {\n" + >+ " return dubious == null ? dubious : null;\n" + >+ " }\n" + >+ "}\n" >+ }, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in X.java (at line 5)\n" + >+ " return dubious == null ? dubious : null;\n" + >+ " ^^^^^^^\n" + >+ "Null comparison always yields false: The variable dubious cannot be null at this location\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 5)\n" + >+ " return dubious == null ? dubious : null;\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + >+ "----------\n"); >+} >+// don't apply any default annotations to return void >+public void test_nonnull_return_013() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO, JavaCore.ERROR); >+ runConformTestWithLibs( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@NonNullByDefault\n" + >+ "public class X {\n" + >+ " void getObject() {}\n" + >+ "}\n", >+ "Y.java", >+ "public class Y extends X {\n" + >+ " @Override\n" + >+ " void getObject() {}\n" + // don't complain, void takes no (default) annotation >+ "}\n" >+ }, >+ customOptions, >+ ""); >+} >+// bug 365835: [compiler][null] inconsistent error reporting. >+public void test_nonnull_return_014() { >+ runNegativeTestWithLibs( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.NonNull;\n" + >+ "\n" + >+ "public class X {\n" + >+ " @NonNull\n" + >+ " public Object foo(Object x, int y) {\n" + >+ " @NonNull Object local;\n" + >+ " while (true) {\n" + >+ " if (y == 4) {\n" + >+ " local = x; // error\n" + >+ " return x; // only a warning.\n" + >+ " }\n" + >+ " x = null;\n" + >+ " }\n" + >+ " }\n" + >+ "}" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 9)\n" + >+ " local = x; // error\n" + >+ " ^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value can be null\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 10)\n" + >+ " return x; // only a warning.\n" + >+ " ^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value can be null\n" + >+ "----------\n"); >+} >+//suppress an error regarding null-spec violation >+public void test_suppress_001() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_PB_SUPPRESS_OPTIONAL_ERRORS, JavaCore.ENABLED); >+ runConformTestWithLibs( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " @SuppressWarnings(\"null\")\n" + >+ " @NonNull Object getObject(@Nullable Object o) {\n" + >+ " return o;\n" + // 'o' is only potentially null >+ " }\n" + >+ "}\n" >+ }, >+ customOptions, >+ ""); >+} >+// mixed use of fully qualified name / explicit import >+public void test_annotation_import_001() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_NULLABLE_ANNOTATION_NAME, "org.foo.Nullable"); >+ customOptions.put(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, "org.foo.NonNull"); >+ runConformTestWithLibs( >+ new String[] { >+ CUSTOM_NULLABLE_NAME, >+ CUSTOM_NULLABLE_CONTENT, >+ CUSTOM_NONNULL_NAME, >+ CUSTOM_NONNULL_CONTENT, >+ "Lib.java", >+ "public class Lib {\n" + >+ " @org.foo.NonNull Object getObject() { return new Object(); }\n" + // FQN >+ "}\n", >+ "X.java", >+ "import org.foo.NonNull;\n" + // explicit import >+ "public class X {\n" + >+ " @NonNull Object getObject(@NonNull Lib l) {\n" + >+ " return l.getObject();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ customOptions, >+ ""); >+} >+ >+// use of explicit imports throughout >+public void test_annotation_import_002() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_NULLABLE_ANNOTATION_NAME, "org.foo.Nullable"); >+ customOptions.put(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, "org.foo.NonNull"); >+ runConformTest( >+ new String[] { >+ CUSTOM_NULLABLE_NAME, >+ CUSTOM_NULLABLE_CONTENT, >+ CUSTOM_NONNULL_NAME, >+ CUSTOM_NONNULL_CONTENT, >+ "Lib.java", >+ "import org.foo.NonNull;\n" + >+ "public class Lib {\n" + >+ " @NonNull Object getObject() { return new Object(); }\n" + >+ "}\n", >+ "X.java", >+ "import org.foo.NonNull;\n" + >+ "public class X {\n" + >+ " @NonNull Object getObject(@org.foo.Nullable String dummy, @NonNull Lib l) {\n" + >+ " Object o = l.getObject();" + >+ " return o;\n" + >+ " }\n" + >+ "}\n" >+ }, >+ customOptions, >+ ""); >+} >+// explicit import of existing annotation types >+// using a Lib without null specifications >+public void test_annotation_import_005() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO, JavaCore.ERROR); >+ customOptions.put(JavaCore.COMPILER_NULLABLE_ANNOTATION_NAME, "org.foo.MayBeNull"); >+ customOptions.put(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, "org.foo.MustNotBeNull"); >+ runNegativeTest( >+ true/*shouldFlushOutputDirectory*/, >+ new String[] { >+ "org/foo/MayBeNull.java", >+ "package org.foo;\n" + >+ "import java.lang.annotation.*;\n" + >+ "@Retention(RetentionPolicy.CLASS)\n" + >+ "public @interface MayBeNull {}\n", >+ >+ "org/foo/MustNotBeNull.java", >+ "package org.foo;\n" + >+ "import java.lang.annotation.*;\n" + >+ "@Retention(RetentionPolicy.CLASS)\n" + >+ "public @interface MustNotBeNull {}\n", >+ >+ "Lib.java", >+ "public class Lib {\n" + >+ " Object getObject() { return new Object(); }\n" + >+ "}\n", >+ "X.java", >+ "import org.foo.*;\n" + >+ "public class X {\n" + >+ " @MustNotBeNull Object getObject(@MustNotBeNull Lib l) {\n" + >+ " return l.getObject();\n" + >+ " }\n" + >+ "}\n", >+ >+ }, >+ null /*no libs*/, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in X.java (at line 4)\n" + >+ " return l.getObject();\n" + >+ " ^^^^^^^^^^^^^\n" + >+ "Potential type mismatch: required \'@MustNotBeNull Object\' but nullness of the provided value is unknown\n" + >+ "----------\n", >+ JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); >+} >+// a non-null method returns a value obtained from an unannotated method, missing annotation types >+public void test_annotation_import_006() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO, JavaCore.ERROR); >+ customOptions.put(JavaCore.COMPILER_NULLABLE_ANNOTATION_NAME, "org.foo.MayBeNull"); >+ customOptions.put(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, "org.foo.MustNotBeNull"); >+ runNegativeTest( >+ true/*shouldFlushOutputDirectory*/, >+ new String[] { >+ "Lib.java", >+ "public class Lib {\n" + >+ " Object getObject() { return new Object(); }\n" + >+ "}\n", >+ "X.java", >+ "public class X {\n" + >+ " @MustNotBeNull Object getObject(@MustNotBeNull Lib l) {\n" + >+ " return l.getObject();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ null /* no libs */, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in X.java (at line 2)\n" + >+ " @MustNotBeNull Object getObject(@MustNotBeNull Lib l) {\n" + >+ " ^^^^^^^^^^^^^\n" + >+ "MustNotBeNull cannot be resolved to a type\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 2)\n" + >+ " @MustNotBeNull Object getObject(@MustNotBeNull Lib l) {\n" + >+ " ^^^^^^^^^^^^^\n" + >+ "MustNotBeNull cannot be resolved to a type\n" + >+ "----------\n", >+ JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); >+} >+// using nullness defaulting to nonnull, missing annotation types, no longer a problem >+public void test_annotation_import_007() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO, JavaCore.ERROR); >+ customOptions.put(JavaCore.COMPILER_NULLABLE_ANNOTATION_NAME, "org.foo.MayBeNull"); >+ customOptions.put(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, "org.foo.MustNotBeNull"); >+ customOptions.put(JavaCore.COMPILER_NONNULL_IS_DEFAULT, JavaCore.ENABLED); >+ runConformTestWithLibs( >+ new String[] { >+ "Lib.java", >+ "public class Lib {\n" + >+ " Object getObject() { return new Object(); }\n" + >+ "}\n", >+ "X.java", >+ "public class X {\n" + >+ " Object getObject(Lib l) {\n" + >+ " return l.getObject();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ customOptions, >+ ""); >+} >+ >+// a null annotation is illegally used on a class: >+public void test_illegal_annotation_001() { >+ runNegativeTest( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@NonNull public class X {\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 2)\n" + >+ " @NonNull public class X {\n" + >+ " ^^^^^^^^\n" + >+ "The annotation @NonNull is disallowed for this location\n" + >+ "----------\n", >+ this.LIBS, >+ false/*shouldFlush*/); >+} >+// this test has been removed: >+// setting default to nullable, default applies to a parameter >+// public void test_default_nullness_001() >+ >+// a null annotation is illegally defined by its simple name >+// disabled because specific error is not currently raised >+public void _test_illegal_annotation_002() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, "NichtNull"); >+ runNegativeTestWithLibs( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ "}\n" >+ }, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in X.java (at line 1)\n" + >+ " public class X {\n" + >+ " ^\n" + >+ "Cannot use the unqualified name \'NichtNull\' as an annotation name for null specification\n" + >+ "----------\n"); >+} >+ >+// a null annotation is illegally used on a void method: >+public void test_illegal_annotation_003() { >+ runNegativeTest( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " @NonNull void foo() {}\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 3)\n" + >+ " @NonNull void foo() {}\n" + >+ " ^^^^^^^^^^^^^\n" + >+ "The nullness annotation @NonNull is not applicable for the primitive type void\n" + >+ "----------\n", >+ this.LIBS, >+ false/*shouldFlush*/); >+} >+ >+// a null annotation is illegally used on a primitive type parameter >+public void test_illegal_annotation_004() { >+ runNegativeTest( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " void foo(@Nullable int i) {}\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 3)\n" + >+ " void foo(@Nullable int i) {}\n" + >+ " ^^^^^^^^^^^^^\n" + >+ "The nullness annotation @Nullable is not applicable for the primitive type int\n" + >+ "----------\n", >+ this.LIBS, >+ false/*shouldFlush*/); >+} >+ >+// a null annotation is illegally used on a primitive type local var >+public void test_illegal_annotation_005() { >+ runNegativeTest( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " int foo() {\n" + >+ " @Nullable int i = 3;\n" + >+ " return i;\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 4)\n" + >+ " @Nullable int i = 3;\n" + >+ " ^^^^^^^^^^^^^\n" + >+ "The nullness annotation @Nullable is not applicable for the primitive type int\n" + >+ "----------\n", >+ this.LIBS, >+ false/*shouldFlush*/); >+} >+ >+// a configured annotation type does not exist >+// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=186342#c133 >+public void test_illegal_annotation_006() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_NULLABLE_ANNOTATION_NAME, "nullAnn.Nullable"); >+ runNegativeTestWithLibs( >+ new String[] { >+ "p/Test.java", >+ "package p;\n" + >+ "import nullAnn.*; // 1 \n" + >+ "\n" + >+ "public class Test { \n" + >+ "\n" + >+ " void foo(@nullAnn.Nullable Object o) { // 2\n" + >+ " o.toString(); \n" + >+ " }\n" + >+ "}" >+ }, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in p\\Test.java (at line 2)\n" + >+ " import nullAnn.*; // 1 \n" + >+ " ^^^^^^^\n" + >+ "The import nullAnn cannot be resolved\n" + >+ "----------\n" + >+ "2. ERROR in p\\Test.java (at line 6)\n" + >+ " void foo(@nullAnn.Nullable Object o) { // 2\n" + >+ " ^^^^^^^\n" + >+ "nullAnn cannot be resolved to a type\n" + >+ "----------\n"); >+} >+ >+// a configured annotation type does not exist >+// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=186342#c186 >+public void test_illegal_annotation_007() { >+ Map customOptions = getCompilerOptions(); >+ runNegativeTestWithLibs( >+ new String[] { >+ "p/Test.java", >+ "package p;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "interface TestInt{\n" + >+ " @NonNull Object foo();\n" + >+ "}\n" + >+ "\n" + >+ "public class Test { \n" + >+ " void bar() {" + >+ " new TestInt() {\n" + >+ " @org public Object foo() {\n" + >+ " }\n" + >+ " };\n" + >+ " }\n" + >+ "}" >+ }, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in p\\Test.java (at line 9)\n" + >+ " @org public Object foo() {\n" + >+ " ^^^\n" + >+ "org cannot be resolved to a type\n" + >+ "----------\n" + >+ "2. ERROR in p\\Test.java (at line 9)\n" + >+ " @org public Object foo() {\n" + >+ " ^^^^^^\n" + >+ "The return type is incompatible with the @NonNull return from TestInt.foo()\n" + >+ "----------\n"); >+} >+ >+public void test_default_nullness_002() { >+ Map customOptions = getCompilerOptions(); >+// customOptions.put(CompilerOptions.OPTION_ReportPotentialNullSpecViolation, JavaCore.ERROR); >+// This option currently does nothing: >+// customOptions.put(JavaCore.COMPILER_NONNULL_IS_DEFAULT, JavaCore.ENABLED); >+ runNegativeTestWithLibs( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@NonNullByDefault\n" + >+ "public class X {\n" + >+ " Object getObject(@Nullable Object o) {\n" + >+ " return new Object();\n" + >+ " }\n" + >+ "}\n", >+ "Y.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@NonNullByDefault\n" + >+ "public class Y extends X {\n" + >+ " @Override\n" + >+ " @Nullable Object getObject(Object o) {\n" + // complain illegal return redef and inherited annot is not repeated >+ " return o;\n" + >+ " }\n" + >+ "}\n", >+ }, >+ customOptions, >+ // main error: >+ "----------\n" + >+ "1. ERROR in Y.java (at line 5)\n" + >+ " @Nullable Object getObject(Object o) {\n" + >+ " ^^^^^^^^^^^^^^^^\n" + >+ "The return type is incompatible with the @NonNull return from X.getObject(Object)\n" + >+ "----------\n" + >+ // additional error: >+ "2. ERROR in Y.java (at line 5)\n" + >+ " @Nullable Object getObject(Object o) {\n" + >+ " ^^^^^^\n" + >+ "Illegal redefinition of parameter o, inherited method from X declares this parameter as @Nullable\n" + >+ "----------\n"); >+} >+// package default is non-null >+public void test_default_nullness_003() { >+ Map customOptions = getCompilerOptions(); >+// customOptions.put(CompilerOptions.OPTION_ReportPotentialNullSpecViolation, JavaCore.ERROR); >+ runNegativeTestWithLibs( >+ new String[] { >+ "p1/X.java", >+ "package p1;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@NonNullByDefault\n" + >+ "public class X {\n" + >+ " protected Object getObject(@Nullable Object o) {\n" + >+ " return new Object();\n" + >+ " }\n" + >+ "}\n", >+ "p2/package-info.java", >+ "@org.eclipse.jdt.annotation.NonNullByDefault\n" + >+ "package p2;\n", >+ "p2/Y.java", >+ "package p2;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class Y extends p1.X {\n" + >+ " @Override\n" + >+ " protected @Nullable Object getObject(@Nullable Object o) {\n" + >+ " bar(o);\n" + >+ " return o;\n" + >+ " }\n" + >+ " void bar(Object o2) { }\n" + // parameter is nonnull per package default >+ "}\n" >+ }, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in p2\\Y.java (at line 5)\n" + >+ " protected @Nullable Object getObject(@Nullable Object o) {\n" + >+ " ^^^^^^^^^^^^^^^^\n" + >+ "The return type is incompatible with the @NonNull return from X.getObject(Object)\n" + >+ "----------\n" + >+ "2. ERROR in p2\\Y.java (at line 6)\n" + >+ " bar(o);\n" + >+ " ^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value can be null\n" + >+ "----------\n"); >+} >+// package level default is consumed from package-info.class, similarly for type level default >+public void test_default_nullness_003a() { >+ Map customOptions = getCompilerOptions(); >+// customOptions.put(CompilerOptions.OPTION_ReportPotentialNullSpecViolation, JavaCore.ERROR); >+ runConformTestWithLibs( >+ new String[] { >+ "p1/X.java", >+ "package p1;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@NonNullByDefault\n" + >+ "public class X {\n" + >+ " protected Object getObject(@Nullable Object o) {\n" + >+ " return new Object();\n" + >+ " }\n" + >+ " protected void bar(Object o2) { }\n" + // parameter is nonnull per type default >+ "}\n", >+ "p2/package-info.java", >+ "@org.eclipse.jdt.annotation.NonNullByDefault\n" + >+ "package p2;\n", >+ }, >+ customOptions, >+ ""); >+ // check if default is visible from package-info.class. >+ runNegativeTestWithLibs( >+ false, // don't flush >+ new String[] { >+ "p2/Y.java", >+ "package p2;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class Y extends p1.X {\n" + >+ " @Override\n" + >+ " protected @Nullable Object getObject(@Nullable Object o) {\n" + // can't override inherited default nonnull >+ " bar(o);\n" + // parameter is nonnull in super class's .class file >+ " accept(o);\n" + >+ " return o;\n" + >+ " }\n" + >+ " void accept(Object a) {}\n" + // governed by package level default >+ "}\n" >+ }, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in p2\\Y.java (at line 5)\n" + >+ " protected @Nullable Object getObject(@Nullable Object o) {\n" + >+ " ^^^^^^^^^^^^^^^^\n" + >+ "The return type is incompatible with the @NonNull return from X.getObject(Object)\n" + >+ "----------\n" + >+ "2. ERROR in p2\\Y.java (at line 6)\n" + >+ " bar(o);\n" + >+ " ^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value can be null\n" + >+ "----------\n" + >+ "3. ERROR in p2\\Y.java (at line 7)\n" + >+ " accept(o);\n" + >+ " ^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value can be null\n" + >+ "----------\n"); >+} >+// same as test_default_nullness_003a, but default-induced annotations are combined with explicit ones (not null related) >+public void test_default_nullness_003b() { >+ Map customOptions = getCompilerOptions(); >+ runConformTestWithLibs( >+ new String[] { >+ "p1/Annot.java", >+ "package p1;\n" + >+ "import static java.lang.annotation.ElementType.*;\n" + >+ "import java.lang.annotation.*;\n" + >+ "@Retention(RetentionPolicy.CLASS)\n" + >+ "@Target({METHOD,PARAMETER})\n" + >+ "public @interface Annot {}\n", >+ "p1/X.java", >+ "package p1;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@NonNullByDefault\n" + >+ "public class X {\n" + >+ " protected @Annot Object getObject(@Annot @Nullable Object o) {\n" + >+ " return new Object();\n" + >+ " }\n" + >+ " protected @Annot void bar(@Annot Object o2) { }\n" + // parameter is nonnull per type default >+ "}\n", >+ "p2/package-info.java", >+ "@org.eclipse.jdt.annotation.NonNullByDefault\n" + >+ "package p2;\n", >+ }, >+ customOptions, >+ ""); >+ // check if default is visible from package-info.class. >+ runNegativeTestWithLibs( >+ false, // don't flush >+ new String[] { >+ "p2/Y.java", >+ "package p2;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class Y extends p1.X {\n" + >+ " @Override\n" + >+ " protected @Nullable Object getObject(@Nullable Object o) {\n" + // can't override inherited default nonnull >+ " bar(o);\n" + // parameter is nonnull in super class's .class file >+ " accept(o);\n" + >+ " return o;\n" + >+ " }\n" + >+ " void accept(@p1.Annot Object a) {}\n" + // governed by package level default >+ "}\n" >+ }, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in p2\\Y.java (at line 5)\n" + >+ " protected @Nullable Object getObject(@Nullable Object o) {\n" + >+ " ^^^^^^^^^^^^^^^^\n" + >+ "The return type is incompatible with the @NonNull return from X.getObject(Object)\n" + >+ "----------\n" + >+ "2. ERROR in p2\\Y.java (at line 6)\n" + >+ " bar(o);\n" + >+ " ^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value can be null\n" + >+ "----------\n" + >+ "3. ERROR in p2\\Y.java (at line 7)\n" + >+ " accept(o);\n" + >+ " ^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value can be null\n" + >+ "----------\n"); >+} >+// don't apply type-level default to non-reference type >+public void test_default_nullness_004() { >+ Map customOptions = getCompilerOptions(); >+// customOptions.put(CompilerOptions.OPTION_ReportPotentialNullSpecViolation, JavaCore.ERROR); >+ runConformTestWithLibs( >+ new String[] { >+ "p1/X.java", >+ "package p1;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@NonNullByDefault\n" + >+ "public class X {\n" + >+ " protected Object getObject(boolean o) {\n" + >+ " return new Object();\n" + >+ " }\n" + >+ "}\n", >+ "p2/Y.java", >+ "package p2;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class Y extends p1.X {\n" + >+ " @Override\n" + >+ " protected @NonNull Object getObject(boolean o) {\n" + >+ " return o ? this : new Object();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ customOptions, >+ ""); >+} >+// package default is non-null >+// see also Bug 354536 - compiling package-info.java still depends on the order of compilation units >+public void test_default_nullness_005() { >+ Map customOptions = getCompilerOptions(); >+// customOptions.put(CompilerOptions.OPTION_ReportPotentialNullSpecViolation, JavaCore.ERROR); >+ customOptions.put(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, "org.foo.NonNull"); >+ runNegativeTestWithLibs( >+ new String[] { >+ "p1/X.java", >+ "package p1;\n" + >+ "public class X {\n" + >+ " class Inner {" + >+ " protected Object getObject(String s) {\n" + >+ " return null;\n" + >+ " }\n" + >+ " }\n" + >+ "}\n", >+ "p1/package-info.java", >+ "@org.eclipse.jdt.annotation.NonNullByDefault\n" + >+ "package p1;\n", >+ CUSTOM_NONNULL_NAME, >+ CUSTOM_NONNULL_CONTENT >+ }, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in p1\\X.java (at line 4)\n" + >+ " return null;\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + >+ "----------\n"); >+} >+// package default is non-null, package-info.java read before the annotation type >+// compile order: beginToCompile(X.Inner) triggers reading of package-info.java before the annotation type was read >+public void test_default_nullness_006() { >+ Map customOptions = getCompilerOptions(); >+// customOptions.put(CompilerOptions.OPTION_ReportPotentialNullSpecViolation, JavaCore.ERROR); >+ customOptions.put(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, "org.foo.NonNull"); >+ runNegativeTestWithLibs( >+ new String[] { >+ "p1/package-info.java", >+ "@org.eclipse.jdt.annotation.NonNullByDefault\n" + >+ "package p1;\n", >+ "p1/X.java", >+ "package p1;\n" + >+ "public class X {\n" + >+ " class Inner {" + >+ " protected Object getObject(String s) {\n" + >+ " return null;\n" + >+ " }\n" + >+ " }\n" + >+ "}\n", >+ CUSTOM_NONNULL_NAME, >+ CUSTOM_NONNULL_CONTENT >+ }, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in p1\\X.java (at line 4)\n" + >+ " return null;\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + >+ "----------\n"); >+} >+// global default nonnull, but return may be null >+// DISABLED due to dysfunctional global default after Bug 366063 - Compiler should not add synthetic @NonNull annotations >+public void _test_default_nullness_007() { >+ Map customOptions = getCompilerOptions(); >+// customOptions.put(CompilerOptions.OPTION_ReportPotentialNullSpecViolation, JavaCore.ERROR); >+ customOptions.put(JavaCore.COMPILER_NONNULL_IS_DEFAULT, JavaCore.ENABLED); >+ runNegativeTestWithLibs( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " @Nullable Object dangerous() {\n" + >+ " return null;\n" + >+ " }\n" + >+ " Object broken() {\n" + >+ " return dangerous();\n" + >+ " }\n" + >+ "}\n", >+ >+ }, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in X.java (at line 7)\n" + >+ " return dangerous();\n" + >+ " ^^^^^^^^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value can be null\n" + >+ "----------\n"); >+} >+ >+// cancel type level default to comply with super specification >+public void test_default_nullness_008() { >+ Map customOptions = getCompilerOptions(); >+// customOptions.put(CompilerOptions.OPTION_ReportPotentialNullSpecViolation, JavaCore.ERROR); >+ runConformTestWithLibs( >+ new String[] { >+ "p1/X.java", >+ "package p1;\n" + >+ "public class X {\n" + >+ " protected Object getObject(Object o) {\n" + >+ " return new Object();\n" + >+ " }\n" + >+ "}\n", >+ "p2/Y.java", >+ "package p2;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@NonNullByDefault\n" + >+ "public class Y extends p1.X {\n" + >+ " @Override\n" + >+ " @NonNullByDefault(false)\n" + >+ " protected Object getObject(Object o) {\n" + >+ " if (o.toString().length() == 0)\n" + // dereference without a warning >+ " return null;\n" + // return null without a warning >+ " return o.toString();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ customOptions, >+ ""); >+} >+ >+// cancel outer type level default to comply with super specification >+public void test_default_nullness_009() { >+ Map customOptions = getCompilerOptions(); >+// customOptions.put(CompilerOptions.OPTION_ReportPotentialNullSpecViolation, JavaCore.ERROR); >+ runNegativeTestWithLibs( >+ new String[] { >+ "p1/X.java", >+ "package p1;\n" + >+ "public class X {\n" + >+ " protected Object getObject(Object o) {\n" + >+ " return new Object();\n" + >+ " }\n" + >+ "}\n", >+ "p2/Y.java", >+ "package p2;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@NonNullByDefault\n" + >+ "public class Y { \n" + >+ " @NonNullByDefault(false)\n" + >+ " static class Z extends p1.X {\n" + >+ " @Override\n" + >+ " protected Object getObject(Object o) {\n" + >+ " if (o.toString().length() == 0) {\n" + >+ " o = null;\n" + // assign null without a warning >+ " bar(o); // error: arg is declared @NonNull\n" + >+ " return null;\n" + >+ " }\n" + >+ " return o.toString();\n" + >+ " }\n" + >+ " String bar(@NonNull Object o) {\n" + >+ " return getObject(o).toString();" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in p2\\Y.java (at line 11)\n" + >+ " bar(o); // error: arg is declared @NonNull\n" + >+ " ^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + >+ "----------\n"); >+} >+// non-null declarations are redundant within a default scope. >+public void test_default_nullness_010() { >+ Map customOptions = getCompilerOptions(); >+// customOptions.put(CompilerOptions.OPTION_ReportPotentialNullSpecViolation, JavaCore.ERROR); >+ runConformTestWithLibs( >+ new String[] { >+ "p2/Y.java", >+ "package p2;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@NonNullByDefault\n" + >+ "public class Y {\n" + >+ " protected @NonNull Object getObject(@NonNull Object o) {\n" + >+ " return o;\n" + >+ " }\n" + >+ "}\n" >+ }, >+ customOptions, >+ "----------\n" + >+ "1. WARNING in p2\\Y.java (at line 5)\n" + >+ " protected @NonNull Object getObject(@NonNull Object o) {\n" + >+ " ^^^^^^^^^^^^^^^\n" + >+ "The nullness annotation is redundant with a default that applies to this location\n" + >+ "----------\n" + >+ "2. WARNING in p2\\Y.java (at line 5)\n" + >+ " protected @NonNull Object getObject(@NonNull Object o) {\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "The nullness annotation is redundant with a default that applies to this location\n" + >+ "----------\n"); >+} >+// package-info declares nonnull-by-default >+// special compile order due to import of type from that package >+// cf. https://bugs.eclipse.org/bugs/show_bug.cgi?id=186342#add_comment >+public void test_default_nullness_011() { >+ runNegativeTestWithLibs( >+ new String[] { >+ "Main.java", >+ "import p1.C;\n" + >+ "public class Main {\n" + >+ " void test(@org.eclipse.jdt.annotation.NonNull Object o) {\n" + >+ " o = null;\n" + >+ " new C(null);\n" + >+ " }\n" + >+ "}\n", >+ "p1/C.java", >+ "package p1;\n" + >+ "@org.eclipse.jdt.annotation.NonNullByDefault\n" + >+ "public class C {\n" + >+ " public C (Object o) {}\n" + >+ "}\n", >+ "p1/package-info.java", >+ "@org.eclipse.jdt.annotation.NonNullByDefault\n" + >+ "package p1;\n" >+ }, >+ "----------\n" + >+ "1. ERROR in Main.java (at line 4)\n" + >+ " o = null;\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + >+ "----------\n" + >+ "2. ERROR in Main.java (at line 5)\n" + >+ " new C(null);\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + >+ "----------\n" + >+ "----------\n" + >+ "1. WARNING in p1\\C.java (at line 2)\n" + >+ " @org.eclipse.jdt.annotation.NonNullByDefault\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with a default specified for the enclosing package p1\n" + >+ "----------\n"); >+} >+// Bug 365836 - [compiler][null] Incomplete propagation of null defaults. >+public void test_default_nullness_012() { >+ runNegativeTestWithLibs( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.NonNullByDefault;\n" + >+ "import org.eclipse.jdt.annotation.Nullable;\n" + >+ "\n" + >+ "public class X {\n" + >+ " @NonNullByDefault \n" + >+ " public void foo(@Nullable String [] args) {\n" + >+ " class local {\n" + >+ " void zoo(Object o) {\n" + >+ " }\n" + >+ " };\n" + >+ " new local().zoo(null); // defaults applying from foo\n" + >+ " }\n" + >+ "}" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 11)\n" + >+ " new local().zoo(null); // defaults applying from foo\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + >+ "----------\n"); >+} >+// Bug 365836 - [compiler][null] Incomplete propagation of null defaults. >+public void test_default_nullness_013() { >+ runNegativeTestWithLibs( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.NonNullByDefault;\n" + >+ "import org.eclipse.jdt.annotation.Nullable;\n" + >+ "\n" + >+ "@SuppressWarnings(\"unused\")\n" + >+ "public class X {\n" + >+ " @NonNullByDefault \n" + >+ " public void foo(@Nullable String [] args) {\n" + >+ " class local {\n" + >+ " class Deeply {\n" + >+ " Object zoo() {\n" + >+ " return null; // defaults applying from foo\n" + >+ " }\n" + >+ " }\n" + >+ " };\n" + >+ " }\n" + >+ "}" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 11)\n" + >+ " return null; // defaults applying from foo\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + >+ "----------\n"); >+} >+// bug 367154 - [compiler][null] Problem in propagating null defaults. >+public void test_default_nullness_014() { >+ runNegativeTestWithLibs( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.NonNullByDefault;\n" + >+ "import org.eclipse.jdt.annotation.Nullable;\n" + >+ "\n" + >+ "@SuppressWarnings(\"unused\")\n" + >+ "public class X {\n" + >+ "\n" + >+ " public void foo(@Nullable String [] args) {\n" + >+ " @NonNullByDefault\n" + >+ " class local {\n" + >+ " class Deeply {\n" + >+ " Object zoo() {\n" + >+ " return null; // expect error here\n" + >+ " }\n" + >+ " }\n" + >+ " };\n" + >+ " }\n" + >+ "}" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 12)\n" + >+ " return null; // expect error here\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + >+ "----------\n"); >+} >+// bug 367154 - [compiler][null] Problem in propagating null defaults. >+// initializer involved >+public void test_default_nullness_015() { >+ runNegativeTestWithLibs( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.NonNullByDefault;\n" + >+ "import org.eclipse.jdt.annotation.Nullable;\n" + >+ "\n" + >+ "@SuppressWarnings(\"unused\")\n" + >+ "@NonNullByDefault\n" + >+ "public class X {\n" + >+ " {\n" + >+ " class local {\n" + >+ " class Deeply {\n" + >+ " Object zoo() {\n" + >+ " return null; // expect error here\n" + >+ " }\n" + >+ " }\n" + >+ " };\n" + >+ " }\n" + >+ "}" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 11)\n" + >+ " return null; // expect error here\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + >+ "----------\n"); >+} >+ >+// redundant default annotations - class vs. inner class >+public void test_redundant_annotation_01() { >+ Map customOptions = getCompilerOptions(); >+// customOptions.put(CompilerOptions.OPTION_ReportPotentialNullSpecViolation, JavaCore.ERROR); >+ runConformTestWithLibs( >+ new String[] { >+ "p2/Y.java", >+ "package p2;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@NonNullByDefault\n" + >+ "public class Y {\n" + >+ " @NonNullByDefault class Inner {\n" + >+ " @NonNullByDefault class DeepInner {}\n" + >+ " }\n" + >+ " class Inner2 {\n" + >+ " @NonNullByDefault class DeepInner2 {\n" + >+ " }\n" + >+ " void foo() {\n" + >+ " @SuppressWarnings(\"unused\") @NonNullByDefault class Local {}\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" + >+ "@NonNullByDefault class V {}\n", >+ "p3/package-info.java", >+ "@org.eclipse.jdt.annotation.NonNullByDefault package p3;\n", >+ "p3/Z.java", >+ "package p3;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@NonNullByDefault\n" + >+ "public class Z {\n" + >+ "}\n" + >+ "class X {\n" + >+ " @NonNullByDefault class Inner {}\n" + >+ " class Inner2 {\n" + >+ " @NonNullByDefault class DeepInner {}\n" + >+ " }\n" + >+ "}\n" >+ }, >+ customOptions, >+ "----------\n" + >+ "1. WARNING in p2\\Y.java (at line 5)\n" + >+ " @NonNullByDefault class Inner {\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with a default specified for the enclosing type Y\n" + >+ "----------\n" + >+ "2. WARNING in p2\\Y.java (at line 6)\n" + >+ " @NonNullByDefault class DeepInner {}\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with a default specified for the enclosing type Y.Inner\n" + >+ "----------\n" + >+ "3. WARNING in p2\\Y.java (at line 9)\n" + >+ " @NonNullByDefault class DeepInner2 {\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with a default specified for the enclosing type Y\n" + >+ "----------\n" + >+ "4. WARNING in p2\\Y.java (at line 12)\n" + >+ " @SuppressWarnings(\"unused\") @NonNullByDefault class Local {}\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with a default specified for the enclosing type Y\n" + >+ "----------\n" + >+ "----------\n" + >+ "1. WARNING in p3\\Z.java (at line 3)\n" + >+ " @NonNullByDefault\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with a default specified for the enclosing package p3\n" + >+ "----------\n" + >+ "2. WARNING in p3\\Z.java (at line 7)\n" + >+ " @NonNullByDefault class Inner {}\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with a default specified for the enclosing package p3\n" + >+ "----------\n" + >+ "3. WARNING in p3\\Z.java (at line 9)\n" + >+ " @NonNullByDefault class DeepInner {}\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with a default specified for the enclosing package p3\n" + >+ "----------\n"); >+} >+ >+// redundant default annotations - class vs. method >+public void test_redundant_annotation_02() { >+ Map customOptions = getCompilerOptions(); >+ runConformTestWithLibs( >+ new String[] { >+ "p2/Y.java", >+ "package p2;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@NonNullByDefault\n" + >+ "public class Y {\n" + >+ " @NonNullByDefault void foo() {}\n" + >+ "}\n" + >+ "class Z {\n" + >+ " @NonNullByDefault void bar() {\n" + >+ " @NonNullByDefault @SuppressWarnings(\"unused\") class Zork {\n" + >+ " @NonNullByDefault void fubar() {}\n" + >+ " }\n" + >+ " }\n" + >+ " @NonNullByDefault void zink() {\n" + >+ " @SuppressWarnings(\"unused\") class Bork {\n" + >+ " @NonNullByDefault void jubar() {}\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ customOptions, >+ "----------\n" + >+ "1. WARNING in p2\\Y.java (at line 5)\n" + >+ " @NonNullByDefault void foo() {}\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with a default specified for the enclosing type Y\n" + >+ "----------\n" + >+ "2. WARNING in p2\\Y.java (at line 9)\n" + >+ " @NonNullByDefault @SuppressWarnings(\"unused\") class Zork {\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with a default specified for the enclosing method bar()\n" + >+ "----------\n" + >+ "3. WARNING in p2\\Y.java (at line 10)\n" + >+ " @NonNullByDefault void fubar() {}\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with a default specified for the enclosing type Zork\n" + >+ "----------\n" + >+ "4. WARNING in p2\\Y.java (at line 15)\n" + >+ " @NonNullByDefault void jubar() {}\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with a default specified for the enclosing method zink()\n" + >+ "----------\n"); >+} >+ >+//redundant default annotations - class vs. method - generics >+public void test_redundant_annotation_02g() { >+ Map customOptions = getCompilerOptions(); >+ runConformTestWithLibs( >+ new String[] { >+ "p2/Y.java", >+ "package p2;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@NonNullByDefault\n" + >+ "public class Y<TY> {\n" + >+ " @NonNullByDefault <TF> void foo(TF arg) {}\n" + >+ "}\n" + >+ "class Z {\n" + >+ " @NonNullByDefault <TB> void bar() {\n" + >+ " @NonNullByDefault @SuppressWarnings(\"unused\") class Zork {\n" + >+ " @NonNullByDefault void fubar(TB arg) {}\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ customOptions, >+ "----------\n" + >+ "1. WARNING in p2\\Y.java (at line 5)\n" + >+ " @NonNullByDefault <TF> void foo(TF arg) {}\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with a default specified for the enclosing type Y<TY>\n" + >+ "----------\n" + >+ "2. WARNING in p2\\Y.java (at line 9)\n" + >+ " @NonNullByDefault @SuppressWarnings(\"unused\") class Zork {\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with a default specified for the enclosing method bar()\n" + >+ "----------\n" + >+ "3. WARNING in p2\\Y.java (at line 10)\n" + >+ " @NonNullByDefault void fubar(TB arg) {}\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with a default specified for the enclosing type Zork\n" + >+ "----------\n"); >+} >+ >+// redundant default annotations - package / class / method vs global default >+// DISABLED due to dysfunctional global default after Bug 366063 - Compiler should not add synthetic @NonNull annotations >+public void _test_redundant_annotation_03() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_NONNULL_IS_DEFAULT, JavaCore.ENABLED); >+ runConformTestWithLibs( >+ new String[] { >+ "p2/Y.java", >+ "package p2;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@NonNullByDefault\n" + >+ "public class Y {\n" + >+ " @NonNullByDefault void foo() {}\n" + >+ "}\n" + >+ "class Z {\n" + >+ " @NonNullByDefault void bar() {}\n" + >+ "}\n", >+ "p3/package-info.java", >+ "@org.eclipse.jdt.annotation.NonNullByDefault package p3;\n" >+ }, >+ customOptions, >+ "----------\n" + >+ "1. WARNING in p2\\Y.java (at line 3)\n" + >+ " @NonNullByDefault\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with the global default\n" + >+ "----------\n" + >+ "2. WARNING in p2\\Y.java (at line 5)\n" + >+ " @NonNullByDefault void foo() {}\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with a default specified for the enclosing type Y\n" + >+ "----------\n" + >+ "3. WARNING in p2\\Y.java (at line 8)\n" + >+ " @NonNullByDefault void bar() {}\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with the global default\n" + >+ "----------\n" + >+ "----------\n" + >+ "1. WARNING in p3\\package-info.java (at line 1)\n" + >+ " @org.eclipse.jdt.annotation.NonNullByDefault package p3;\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with the global default\n" + >+ "----------\n"); >+} >+ >+// redundant default annotations - class vs. inner class >+// ensure that disabling null annotations also disables this diagnostic >+public void test_redundant_annotation_04() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.DISABLED); >+ runConformTestWithLibs( >+ new String[] { >+ "p2/Y.java", >+ "package p2;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@NonNullByDefault\n" + >+ "public class Y {\n" + >+ " @NonNullByDefault class Inner {\n" + >+ " @NonNullByDefault class DeepInner {}\n" + >+ " }\n" + >+ " class Inner2 {\n" + >+ " @NonNullByDefault class DeepInner2 {\n" + >+ " }\n" + >+ " @NonNullByDefault void foo(@Nullable @NonNull Object arg) {\n" + >+ " @NonNullByDefault class Local {}\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" + >+ "@NonNullByDefault class V {}\n", >+ "p3/package-info.java", >+ "@org.eclipse.jdt.annotation.NonNullByDefault package p3;\n", >+ "p3/Z.java", >+ "package p3;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@NonNullByDefault\n" + >+ "public class Z {\n" + >+ "}\n" + >+ "class X {\n" + >+ " @NonNullByDefault class Inner {}\n" + >+ " class Inner2 {\n" + >+ " @NonNullByDefault class DeepInner {}\n" + >+ " }\n" + >+ "}\n" >+ }, >+ customOptions, >+ ""); >+} >+ >+// contradictory null annotations >+public void test_contradictory_annotations_01() { >+ Map customOptions = getCompilerOptions(); >+ runNegativeTestWithLibs( >+ new String[] { >+ "p2/Y.java", >+ "package p2;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class Y {\n" + >+ " void foo(@NonNull @Nullable Object o) {}\n" + >+ " @Nullable @NonNull Object bar() {\n" + >+ " @NonNull @Nullable Object o = null;\n" + >+ " return o;\n" + >+ " }\n" + >+ "}\n" + >+ "class Z {\n" + >+ " @NonNullByDefault void bar() {}\n" + >+ "}\n" >+ }, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in p2\\Y.java (at line 4)\n" + >+ " void foo(@NonNull @Nullable Object o) {}\n" + >+ " ^^^^^^^^^\n" + >+ "Contradictory null specification; only one of @NonNull and @Nullable can be specified at any location\n" + >+ "----------\n" + >+ "2. ERROR in p2\\Y.java (at line 5)\n" + >+ " @Nullable @NonNull Object bar() {\n" + >+ " ^^^^^^^^\n" + >+ "Contradictory null specification; only one of @NonNull and @Nullable can be specified at any location\n" + >+ "----------\n" + >+ "3. ERROR in p2\\Y.java (at line 6)\n" + >+ " @NonNull @Nullable Object o = null;\n" + >+ " ^^^^^^^^^\n" + >+ "Contradictory null specification; only one of @NonNull and @Nullable can be specified at any location\n" + >+ "----------\n"); >+} >+ >+// a nonnull variable is dereferenced in a loop >+public void test_nonnull_var_in_constrol_structure_1() { >+ Map customOptions = getCompilerOptions(); >+// customOptions.put(CompilerOptions.OPTION_ReportPotentialNullSpecViolation, JavaCore.ERROR); >+// This option currently does nothing: >+// customOptions.put(JavaCore.COMPILER_NONNULL_IS_DEFAULT, JavaCore.ENABLED); >+ runNegativeTestWithLibs( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@NonNullByDefault\n" + >+ "public class X {\n" + >+ " void print4(@NonNull String s) {\n" + >+ " for (int i=0; i<4; i++)\n" + >+ " print(s);\n" + >+ " }\n" + >+ " void print5(@Nullable String s) {\n" + >+ " for (int i=0; i<5; i++)\n" + >+ " print(s);\n" + >+ " }\n" + >+ " void print6(boolean b) {\n" + >+ " String s = b ? null : \"\";\n" + >+ " for (int i=0; i<5; i++)\n" + >+ " print(s);\n" + >+ " }\n" + >+ " void print(@NonNull String s) {\n" + >+ " System.out.print(s);\n" + >+ " }\n" + >+ "}\n", >+ >+ }, >+ customOptions, >+ "----------\n" + >+ "1. WARNING in X.java (at line 4)\n" + >+ " void print4(@NonNull String s) {\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "The nullness annotation is redundant with a default that applies to this location\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 10)\n" + >+ " print(s);\n" + >+ " ^\n" + >+ "Type mismatch: required \'@NonNull String\' but the provided value can be null\n" + >+ "----------\n" + >+ "3. ERROR in X.java (at line 15)\n" + >+ " print(s);\n" + >+ " ^\n" + >+ "Type mismatch: required \'@NonNull String\' but the provided value can be null\n" + >+ "----------\n" + >+ "4. WARNING in X.java (at line 17)\n" + >+ " void print(@NonNull String s) {\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "The nullness annotation is redundant with a default that applies to this location\n" + >+ "----------\n"); >+} >+// a nonnull variable is dereferenced in a finally block >+public void test_nonnull_var_in_constrol_structure_2() { >+ Map customOptions = getCompilerOptions(); >+// customOptions.put(CompilerOptions.OPTION_ReportPotentialNullSpecViolation, JavaCore.ERROR); >+// This option currently does nothing: >+// customOptions.put(JavaCore.COMPILER_NONNULL_IS_DEFAULT, JavaCore.ENABLED); >+ runNegativeTestWithLibs( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;" + >+ "@NonNullByDefault\n" + >+ "public class X {\n" + >+ " void print4(String s) {\n" + >+ " try { /*empty*/ } finally {\n" + >+ " print(s);\n" + >+ " }\n" + >+ " }\n" + >+ " void print5(@Nullable String s) {\n" + >+ " try { /*empty*/ } finally {\n" + >+ " print(s);\n" + >+ " }\n" + >+ " }\n" + >+ " void print6(boolean b) {\n" + >+ " String s = b ? null : \"\";\n" + >+ " try { /*empty*/ } finally {\n" + >+ " print(s);\n" + >+ " }\n" + >+ " }\n" + >+ " void print(String s) {\n" + >+ " System.out.print(s);\n" + >+ " }\n" + >+ "}\n", >+ >+ }, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in X.java (at line 10)\n" + >+ " print(s);\n" + >+ " ^\n" + >+ "Type mismatch: required \'@NonNull String\' but the provided value can be null\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 16)\n" + >+ " print(s);\n" + >+ " ^\n" + >+ "Type mismatch: required \'@NonNull String\' but the provided value can be null\n" + >+ "----------\n"); >+} >+// a nonnull variable is dereferenced in a finally block inside a loop >+public void test_nonnull_var_in_constrol_structure_3() { >+ Map customOptions = getCompilerOptions(); >+// customOptions.put(CompilerOptions.OPTION_ReportPotentialNullSpecViolation, JavaCore.ERROR); >+ customOptions.put(JavaCore.COMPILER_NONNULL_IS_DEFAULT, JavaCore.ENABLED); >+ customOptions.put(JavaCore.COMPILER_PB_REDUNDANT_NULL_ANNOTATION, JavaCore.IGNORE); >+ runNegativeTestWithLibs( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " void print4(@NonNull String s) {\n" + >+ " for (int i=0; i<4; i++)\n" + >+ " try { /*empty*/ } finally {\n" + >+ " print(s);\n" + >+ " }\n" + >+ " }\n" + >+ " void print5(@Nullable String s) {\n" + >+ " for (int i=0; i<5; i++)\n" + >+ " try { /*empty*/ } finally {\n" + >+ " print(s);\n" + >+ " }\n" + >+ " }\n" + >+ " void print6(boolean b) {\n" + >+ " String s = b ? null : \"\";\n" + >+ " for (int i=0; i<4; i++)\n" + >+ " try { /*empty*/ } finally {\n" + >+ " print(s);\n" + >+ " }\n" + >+ " }\n" + >+ " void print(@NonNull String s) {\n" + >+ " System.out.print(s);\n" + >+ " }\n" + >+ "}\n", >+ >+ }, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in X.java (at line 12)\n" + >+ " print(s);\n" + >+ " ^\n" + >+ "Type mismatch: required \'@NonNull String\' but the provided value can be null\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 19)\n" + >+ " print(s);\n" + >+ " ^\n" + >+ "Type mismatch: required \'@NonNull String\' but the provided value can be null\n" + >+ "----------\n"); >+} >+// witness for an AIOOBE in FlowContext.recordExpectedType() >+public void test_message_send_in_control_structure_01() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO, JavaCore.IGNORE); >+ customOptions.put(JavaCore.COMPILER_PB_POTENTIAL_NULL_REFERENCE, JavaCore.WARNING); >+ runNegativeTestWithLibs( >+ new String[] { >+ "p/Scope.java", >+ "package p;\n" + >+ "@org.eclipse.jdt.annotation.NonNullByDefault\n" + >+ "public abstract class Scope {\n" + >+ " public ReferenceBinding findMemberType(char[] typeName, ReferenceBinding enclosingType) {\n" + >+ " ReferenceBinding enclosingSourceType = enclosingSourceType();\n" + >+ " PackageBinding currentPackage = getCurrentPackage();\n" + >+ " CompilationUnitScope unitScope = compilationUnitScope();\n" + >+ " ReferenceBinding memberType = enclosingType.getMemberType(typeName);\n" + >+ " ReferenceBinding currentType = enclosingType;\n" + >+ " ReferenceBinding[] interfacesToVisit = null;\n" + >+ " while (true) {\n" + >+ " ReferenceBinding[] itsInterfaces = currentType.superInterfaces();\n" + >+ " if (itsInterfaces != null) {\n" + >+ " if (interfacesToVisit == null) {\n" + >+ " interfacesToVisit = itsInterfaces;\n" + >+ " }\n" + >+ " }\n" + >+ " unitScope.recordReference(currentType, typeName);\n" + >+ " \n" + >+ " if ((memberType = currentType.getMemberType(typeName)) != null) {\n" + >+ " if (enclosingSourceType == null\n" + >+ " ? memberType.canBeSeenBy(currentPackage)\n" + >+ " : memberType.canBeSeenBy(enclosingType, enclosingSourceType)) {\n" + >+ " return memberType;\n" + >+ " }\n" + >+ " }\n" + >+ " }\n" + >+ " }\n" + >+ " private CompilationUnitScope compilationUnitScope() {\n" + >+ " return compilationUnitScope();\n" + >+ " }\n" + >+ " private PackageBinding getCurrentPackage() {\n" + >+ " return getCurrentPackage();\n" + >+ " }\n" + >+ " private ReferenceBinding enclosingSourceType() {\n" + >+ " return enclosingSourceType();\n" + >+ " }\n" + >+ "}\n", >+ "p/CompilationUnitScope.java", >+ "package p;\n" + >+ "@org.eclipse.jdt.annotation.NonNullByDefault\n" + >+ "public class CompilationUnitScope {\n" + >+ " void recordReference(ReferenceBinding rb, char[] name) {}\n" + >+ "}\n", >+ "p/PackageBinding.java", >+ "package p;\n" + >+ "@org.eclipse.jdt.annotation.NonNullByDefault\n" + >+ "public class PackageBinding {\n" + >+ "}\n", >+ "p/ReferenceBinding.java", >+ "package p;\n" + >+ "@org.eclipse.jdt.annotation.NonNullByDefault\n" + >+ "public class ReferenceBinding {\n" + >+ " ReferenceBinding getMemberType(char[] name) { return this; }\n" + >+ " ReferenceBinding[] superInterfaces() { return new ReferenceBinding[0]; }\n" + >+ " boolean canBeSeenBy(PackageBinding ob) { return true; }\n" + >+ " boolean canBeSeenBy(ReferenceBinding rb, ReferenceBinding rb2) { return true; }\n" + >+ "}\n" >+ }, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in p\\Scope.java (at line 13)\n" + >+ " if (itsInterfaces != null) {\n" + >+ " ^^^^^^^^^^^^^\n" + >+ "Redundant null check: The variable itsInterfaces cannot be null at this location\n" + >+ "----------\n" + >+ "2. ERROR in p\\Scope.java (at line 20)\n" + >+ " if ((memberType = currentType.getMemberType(typeName)) != null) {\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Redundant null check: The variable memberType cannot be null at this location\n" + >+ "----------\n" + >+ "3. ERROR in p\\Scope.java (at line 21)\n" + >+ " if (enclosingSourceType == null\n" + >+ " ^^^^^^^^^^^^^^^^^^^\n" + >+ "Null comparison always yields false: The variable enclosingSourceType cannot be null at this location\n" + >+ "----------\n"); >+} >+// Bug 370930 - NonNull annotation not considered for enhanced for loops >+public void test_message_send_in_control_structure_02() { >+ runNegativeTestWithLibs( >+ new String[] { >+ "Bug370930.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "import java.util.*;\n" + >+ "public class Bug370930 {\n" + >+ " void loop(Collection<String> list) {\n" + >+ " for(@NonNull String s: list) { // warning here: insufficient info on elements\n" + >+ " expectNonNull(s); // no warning here\n" + >+ " }\n" + >+ " }\n" + >+ " \n" + >+ " void expectNonNull(@NonNull String s) {}\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. WARNING in Bug370930.java (at line 5)\n" + >+ " for(@NonNull String s: list) { // warning here: insufficient info on elements\n" + >+ " ^^^^\n" + >+ "Potential type mismatch: required \'@NonNull String\' but nullness of the provided value is unknown\n" + >+ "----------\n"); >+} >+//Bug 370930 - NonNull annotation not considered for enhanced for loops >+public void test_message_send_in_control_structure_03() { >+ runNegativeTestWithLibs( >+ new String[] { >+ "Bug370930.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "import java.util.*;\n" + >+ "public class Bug370930 {\n" + >+ " void loop(Collection<String> list) {\n" + >+ " for(@Nullable String s: list) {\n" + >+ " expectNonNull(s); // warning here\n" + >+ " }\n" + >+ " }\n" + >+ " \n" + >+ " void expectNonNull(@NonNull String s) {}\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in Bug370930.java (at line 6)\n" + >+ " expectNonNull(s); // warning here\n" + >+ " ^\n" + >+ "Type mismatch: required \'@NonNull String\' but the provided value can be null\n" + >+ "----------\n"); >+} >+public void test_assignment_expression_1() { >+ Map customOptions = getCompilerOptions(); >+// customOptions.put(CompilerOptions.OPTION_ReportPotentialNullSpecViolation, JavaCore.ERROR); >+ customOptions.put(JavaCore.COMPILER_NONNULL_IS_DEFAULT, JavaCore.ENABLED); >+ customOptions.put(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK, JavaCore.ERROR); >+ runConformTestWithLibs( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class X {\n" + >+ " @Nullable Object foo() {\n" + >+ " Object o = null;\n" + >+ " boolean keepLooking = true;\n" + >+ " while(keepLooking) {\n" + >+ " if ((o=getO()) != null) {\n" + >+ " return o;\n" + >+ " }\n" + >+ " }\n" + >+ " return null;\n" + >+ " }\n" + >+ "\n" + >+ " private @Nullable Object getO() {\n" + >+ " return new Object();\n" + >+ " }\n" + >+ "}\n", >+ >+ }, >+ customOptions, >+ ""); >+} >+// a nonnull variable is dereferenced in a method of a nested type >+public void test_nesting_1() { >+ Map customOptions = getCompilerOptions(); >+// customOptions.put(CompilerOptions.OPTION_ReportPotentialNullSpecViolation, JavaCore.ERROR); >+// This option currently does nothing: >+// customOptions.put(JavaCore.COMPILER_NONNULL_IS_DEFAULT, JavaCore.ENABLED); >+ runNegativeTestWithLibs( >+ new String[] { >+ "X.java", >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@NonNullByDefault\n" + >+ "public class X {\n" + >+ " void print4(final String s1) {\n" + >+ " for (int i=0; i<3; i++)\n" + >+ " new Runnable() {\n" + >+ " public void run() {\n" + >+ " print(s1);\n" + >+ " }\n" + >+ " }.run();\n" + >+ " }\n" + >+ " void print8(final @Nullable String s2) {\n" + >+ " for (int i=0; i<3; i++)\n" + >+ " new Runnable() {\n" + >+ " public void run() {\n" + >+ " print(s2);\n" + >+ " }\n" + >+ " }.run();\n" + >+ " }\n" + >+ " void print16(boolean b) {\n" + >+ " final String s3 = b ? null : \"\";\n" + >+ " for (int i=0; i<3; i++)\n" + >+ " new Runnable() {\n" + >+ " public void run() {\n" + >+ " @NonNull String s3R = s3;\n" + >+ " }\n" + >+ " }.run();\n" + >+ " }\n" + >+ " void print(String s) {\n" + >+ " System.out.print(s);\n" + >+ " }\n" + >+ "}\n", >+ >+ }, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in X.java (at line 16)\n" + >+ " print(s2);\n" + >+ " ^^\n" + >+ "Type mismatch: required \'@NonNull String\' but the provided value can be null\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 25)\n" + >+ " @NonNull String s3R = s3;\n" + >+ " ^^\n" + >+ "Type mismatch: required \'@NonNull String\' but the provided value can be null\n" + >+ "----------\n"); >+} >+// Test a regression incurred to the OT/J based implementation >+// by the fix in Bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop) >+public void test_constructor_with_nested_class() { >+ runConformTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " final Object o1;\n" + >+ " final Object o2;\n" + >+ " public X() {\n" + >+ " this.o1 = new Object() {\n" + >+ " public String toString() { return \"O1\"; }\n" + >+ " };\n" + >+ " this.o2 = new Object();" + >+ " }\n" + >+ "}\n" >+ }, >+ ""); >+} >+// test analysis disablement, binary type contains annotation >+public void test_options_01() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO, JavaCore.ERROR); >+ runConformTestWithLibs( >+ new String[] { >+ "ContainingInner2.java", >+ "public class ContainingInner2 {\n" + >+ " public ContainingInner2 (@org.eclipse.jdt.annotation.NonNull Object o) {\n" + >+ " }\n" + >+ " public class Inner {\n" + >+ " public <T> Inner (@org.eclipse.jdt.annotation.NonNull T o) {\n" + >+ " }\n" + >+ " }\n" + >+ "}\n", >+ }, >+ null /*customOptions*/, >+ ""); >+ customOptions.put(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.DISABLED); >+ runConformTestWithLibs( >+ false, // flush directory >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " void create() {\n" + >+ " ContainingInner2 container = new ContainingInner2(null);\n" + >+ " ContainingInner2.Inner inner = container.new Inner(null);\n" + >+ " }\n" + >+ "}\n"}, >+ customOptions, >+ "" /* compiler output */); >+} >+// test illegally trying to ignore null spec violations >+public void test_options_02() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_PB_NULL_SPECIFICATION_VIOLATION, JavaCore.IGNORE); // has no effect >+ runNegativeTestWithLibs( >+ new String[] { >+ "Test.java", >+ "public class Test {\n" + >+ " public void foo(@org.eclipse.jdt.annotation.NonNull Object o) {\n" + >+ " o = null;\n" + >+ " Object p = o;\n" + >+ " if (p == null)\n" + >+ " p.toString();\n" + >+ " }\n" + >+ "}\n", >+ }, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in Test.java (at line 3)\n" + >+ " o = null;\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + >+ "----------\n" + >+ "2. ERROR in Test.java (at line 5)\n" + >+ " if (p == null)\n" + >+ " ^\n" + >+ "Null comparison always yields false: The variable p cannot be null at this location\n" + >+ "----------\n" + >+ "3. WARNING in Test.java (at line 6)\n" + >+ " p.toString();\n" + >+ " ^^^^^^^^^^^^\n" + >+ "Dead code\n" + >+ "----------\n"); >+} >+// test setting null spec violations to "warning" >+public void test_options_03() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_PB_NULL_SPECIFICATION_VIOLATION, JavaCore.WARNING); // OK >+ runNegativeTestWithLibs( >+ new String[] { >+ "Test.java", >+ "public class Test {\n" + >+ " public void foo(@org.eclipse.jdt.annotation.NonNull Object o) {\n" + >+ " o = null;\n" + >+ " Object p = o;\n" + >+ " if (p == null)\n" + >+ " p.toString();\n" + >+ " }\n" + >+ "}\n", >+ }, >+ customOptions, >+ "----------\n" + >+ "1. WARNING in Test.java (at line 3)\n" + >+ " o = null;\n" + >+ " ^^^^\n" + >+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + >+ "----------\n" + >+ "2. ERROR in Test.java (at line 5)\n" + >+ " if (p == null)\n" + >+ " ^\n" + >+ "Null comparison always yields false: The variable p cannot be null at this location\n" + >+ "----------\n" + >+ "3. WARNING in Test.java (at line 6)\n" + >+ " p.toString();\n" + >+ " ^^^^^^^^^^^^\n" + >+ "Dead code\n" + >+ "----------\n"); >+} >+} >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java >index 5d3e349..e24388f 100644 >--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2005, 2011 IBM Corporation and others. >+ * Copyright (c) 2005, 2012 IBM Corporation 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 >@@ -18,6 +18,10 @@ > * bug 336428 - [compiler][null] bogus warning "redundant null check" in condition of do {} while() loop > * bug 324178 - [null] ConditionalExpression.nullStatus(..) doesn't take into account the analysis of condition itself > * bug 354554 - [null] conditional with redundant condition yields weak error message >+ * bug 358827 - [1.7] exception analysis for t-w-r spoils null analysis >+ * bug 349326 - [1.7] new warning for missing try-with-resources >+ * bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop) >+ * bug 367879 - Incorrect "Potential null pointer access" warning on statement after try-with-resources within try-finally > *******************************************************************************/ > package org.eclipse.jdt.core.tests.compiler.regression; > >@@ -45,7 +49,7 @@ > // Only the highest compliance level is run; add the VM argument > // -Dcompliance=1.4 (for example) to lower it if needed > static { >-// TESTS_NAMES = new String[] { "testBug348379" }; >+// TESTS_NAMES = new String[] { "testBug360328" }; > // TESTS_NUMBERS = new int[] { 561 }; > // TESTS_RANGE = new int[] { 1, 2049 }; > } >@@ -6014,7 +6018,11 @@ > // https://bugs.eclipse.org/bugs/show_bug.cgi?id=150854 > // (slightly different) variant of 561 > public void test0562_try_catch_unchecked_exception() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.WARNING); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING); > this.runNegativeTest( >+ true, > new String[] { > "X.java", > "import java.io.*;\n" + >@@ -6029,12 +6037,19 @@ > " }\n" + > " }\n" + > "}\n"}, >- "----------\n" + >- "1. ERROR in X.java (at line 8)\n" + >- " o.toString();\n" + >- " ^\n" + >- "Potential null pointer access: The variable o may be null at this location\n" + >- "----------\n", >+ null, >+ options, >+ "----------\n" + >+ "1. WARNING in X.java (at line 6)\n" + >+ " o = new LineNumberReader(new FileReader(\"dummy\"));\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Potential resource leak: \'o\' may not be closed\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 8)\n" + >+ " o.toString();\n" + >+ " ^\n" + >+ "Potential null pointer access: The variable o may be null at this location\n" + >+ "----------\n", > JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); > } > >@@ -6085,6 +6100,8 @@ > // null analysis - try/catch > // https://bugs.eclipse.org/bugs/show_bug.cgi?id=150854 > public void test0564_try_catch_unchecked_exception() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.WARNING); > this.runConformTest( > new String[] { > "X.java", >@@ -6099,13 +6116,21 @@ > " return result;\n" + > " }\n" + > "}"}, >- ""); >+ "", >+ null /* no extra class libraries */, >+ true /* flush output directory */, >+ null /* no vm arguments */, >+ options, >+ null /* no custom requestor*/, >+ false /* do not skip javac for this peculiar test */); > } > > // null analysis - try/catch > // https://bugs.eclipse.org/bugs/show_bug.cgi?id=150854 > // variant > public void test0565_try_catch_unchecked_exception() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.WARNING); > this.runConformTest( > new String[] { > "X.java", >@@ -6121,13 +6146,21 @@ > " return result;\n" + > " }\n" + > "}"}, >- ""); >+ "", >+ null /* no extra class libraries */, >+ true /* flush output directory */, >+ null /* no vm arguments */, >+ options, >+ null /* no custom requestor*/, >+ false /* do not skip javac for this peculiar test */); > } > > // null analysis - try/catch > // https://bugs.eclipse.org/bugs/show_bug.cgi?id=150854 > // variant > public void test0566_try_catch_unchecked_exception() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.WARNING); > this.runConformTest( > new String[] { > "X.java", >@@ -6152,7 +6185,13 @@ > " return null;\n" + > " }\n" + > "}"}, >- ""); >+ "", >+ null /* no extra class libraries */, >+ true /* flush output directory */, >+ null /* no vm arguments */, >+ options, >+ null /* no custom requestor*/, >+ false /* do not skip javac for this peculiar test */); > } > > // null analysis - try/catch for checked exceptions >@@ -14944,4 +14983,474 @@ > "Redundant null check: The variable u cannot be null at this location\n" + > "----------\n"); > } >+// Bug 358827 - [1.7] exception analysis for t-w-r spoils null analysis >+public void test358827() { >+ if (this.complianceLevel >= ClassFileConstants.JDK1_7) { >+ this.runNegativeTest( >+ new String[] { >+ "Bug358827.java", >+ "import java.io.FileReader;\n" + >+ "public class Bug358827 {\n" + >+ " Object foo2() throws Exception {\n" + >+ " String o = null;\n" + >+ " try (FileReader rf = new FileReader(\"file\")){\n" + >+ " o = o.toUpperCase();\n" + >+ " } finally {\n" + >+ " o = \"OK\";\n" + >+ " }\n" + >+ " return o;\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in Bug358827.java (at line 6)\n" + >+ " o = o.toUpperCase();\n" + >+ " ^\n" + >+ "Null pointer access: The variable o can only be null at this location\n" + >+ "----------\n"); >+ } >+} >+// Bug 367879 - Incorrect "Potential null pointer access" warning on statement after try-with-resources within try-finally >+public void test367879() { >+ if (this.complianceLevel >= ClassFileConstants.JDK1_7) { >+ this.runConformTest( >+ new String[] { >+ "Bug367879.java", >+ "import java.io.IOException;\n" + >+ "import java.io.InputStream;\n" + >+ "import java.net.HttpURLConnection;\n" + >+ "import java.net.URL;\n" + >+ "public class Bug367879 {\n" + >+ " public void test() throws IOException {\n" + >+ " HttpURLConnection http = null;\n" + >+ " try {\n" + >+ " http = (HttpURLConnection) new URL(\"http://example.com/\").openConnection();\n" + >+ " try (InputStream in = http.getInputStream()) { /* get input */ }\n" + >+ " http.getURL();\n" + // shouldn't *not* flag as Potential null pointer access >+ " } finally {\n" + >+ " if (http != null) { http.disconnect(); }\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ ""); >+ } >+} >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=256796 >+public void testBug256796() { >+ Map compilerOptions = getCompilerOptions(); >+ compilerOptions.put(CompilerOptions.OPTION_ReportUnnecessaryElse, CompilerOptions.IGNORE); >+ compilerOptions.put(CompilerOptions.OPTION_ReportDeadCode, CompilerOptions.WARNING); >+ compilerOptions.put(CompilerOptions.OPTION_ReportDeadCodeInTrivialIfStatement, CompilerOptions.DISABLED); >+ this.runNegativeTest( >+ new String[] { >+ "Bug.java", >+ "public class Bug {\n" + >+ " private static final boolean TRUE = true;\n" + >+ " private static final boolean FALSE = false;\n" + >+ " void foo() throws Exception {\n" + >+ " if (TRUE) return;\n" + >+ " else System.out.println(\"\");\n" + >+ " System.out.println(\"\");\n" + // not dead code >+ " if (TRUE) throw new Exception();\n" + >+ " else System.out.println(\"\");\n" + >+ " System.out.println(\"\");\n" + // not dead code >+ " if (TRUE) return;\n" + >+ " System.out.println(\"\");\n" + // not dead code >+ " if (FALSE) System.out.println(\"\");\n" + >+ " else return;\n" + >+ " System.out.println(\"\");\n" + // not dead code >+ " if (FALSE) return;\n" + >+ " System.out.println(\"\");\n" + // not dead code >+ " if (false) return;\n" + // dead code >+ " System.out.println(\"\");\n" + >+ " if (true) return;\n" + >+ " System.out.println(\"\");\n" + // dead code >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. WARNING in Bug.java (at line 18)\n" + >+ " if (false) return;\n" + >+ " ^^^^^^^\n" + >+ "Dead code\n" + >+ "----------\n" + >+ "2. WARNING in Bug.java (at line 21)\n" + >+ " System.out.println(\"\");\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Dead code\n" + >+ "----------\n", >+ null, >+ true, >+ compilerOptions); >+} >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=256796 >+public void testBug256796a() { >+ Map compilerOptions = getCompilerOptions(); >+ compilerOptions.put(CompilerOptions.OPTION_ReportUnnecessaryElse, CompilerOptions.IGNORE); >+ compilerOptions.put(CompilerOptions.OPTION_ReportDeadCode, CompilerOptions.WARNING); >+ compilerOptions.put(CompilerOptions.OPTION_ReportDeadCodeInTrivialIfStatement, CompilerOptions.ENABLED); >+ this.runNegativeTest( >+ new String[] { >+ "Bug.java", >+ "public class Bug {\n" + >+ " private static final boolean TRUE = true;\n" + >+ " private static final boolean FALSE = false;\n" + >+ " void foo() throws Exception {\n" + >+ " if (TRUE) return;\n" + >+ " else System.out.println(\"\");\n" + >+ " System.out.println(\"\");\n" + // dead code >+ " }\n" + >+ " void foo2() {\n" + >+ " if (TRUE) return;\n" + >+ " System.out.println(\"\");\n" + // dead code >+ " }\n" + >+ " void foo3() throws Exception {\n" + >+ " if (TRUE) throw new Exception();\n" + >+ " else System.out.println(\"\");\n" + // dead code >+ " System.out.println(\"\");\n" + // dead code >+ " }\n" + >+ " void foo4() throws Exception {\n" + >+ " if (FALSE) System.out.println(\"\");\n" + >+ " else return;\n" + >+ " System.out.println(\"\");\n" + // dead code >+ " }\n" + >+ " void foo5() throws Exception {\n" + >+ " if (FALSE) return;\n" + // dead code >+ " System.out.println(\"\");\n" + >+ " }\n" + >+ " void foo6() throws Exception {\n" + >+ " if (false) return;\n" + // dead code >+ " System.out.println(\"\");\n" + >+ " if (true) return;\n" + >+ " System.out.println(\"\");\n" + // dead code >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. WARNING in Bug.java (at line 6)\n" + >+ " else System.out.println(\"\");\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Dead code\n" + >+ "----------\n" + >+ "2. WARNING in Bug.java (at line 7)\n" + >+ " System.out.println(\"\");\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Dead code\n" + >+ "----------\n" + >+ "3. WARNING in Bug.java (at line 11)\n" + >+ " System.out.println(\"\");\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Dead code\n" + >+ "----------\n" + >+ "4. WARNING in Bug.java (at line 15)\n" + >+ " else System.out.println(\"\");\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Dead code\n" + >+ "----------\n" + >+ "5. WARNING in Bug.java (at line 16)\n" + >+ " System.out.println(\"\");\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Dead code\n" + >+ "----------\n" + >+ "6. WARNING in Bug.java (at line 19)\n" + >+ " if (FALSE) System.out.println(\"\");\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Dead code\n" + >+ "----------\n" + >+ "7. WARNING in Bug.java (at line 21)\n" + >+ " System.out.println(\"\");\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Dead code\n" + >+ "----------\n" + >+ "8. WARNING in Bug.java (at line 24)\n" + >+ " if (FALSE) return;\n" + >+ " ^^^^^^^\n" + >+ "Dead code\n" + >+ "----------\n" + >+ "9. WARNING in Bug.java (at line 28)\n" + >+ " if (false) return;\n" + >+ " ^^^^^^^\n" + >+ "Dead code\n" + >+ "----------\n" + >+ "10. WARNING in Bug.java (at line 31)\n" + >+ " System.out.println(\"\");\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Dead code\n" + >+ "----------\n", >+ null, >+ true, >+ compilerOptions); >+} >+// Bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop) >+public void testBug360328() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR); >+ customOptions.put(CompilerOptions.OPTION_ReportRedundantNullCheck, CompilerOptions.ERROR); >+ runNegativeTest( >+ true, /* flushOutputDir */ >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " void print4() {\n" + >+ " final String s1 = \"\";\n" + >+ " for (int i=0; i<4; i++)\n" + >+ " new Runnable() {\n" + >+ " public void run() {\n" + >+ " if (s1 != null)\n" + >+ " s1.toString();\n" + >+ " }\n" + >+ " }.run();\n" + >+ " }\n" + >+ " void print16(boolean b) {\n" + >+ " final String s3 = b ? null : \"\";\n" + >+ " for (int i=0; i<16; i++)\n" + >+ " new Runnable() {\n" + >+ " public void run() {\n" + >+ " s3.toString();\n" + >+ " }\n" + >+ " }.run();\n" + >+ " }\n" + >+ " void print23() {\n" + >+ " final String s23 = null;\n" + >+ " for (int i=0; i<23; i++)\n" + >+ " new Runnable() {\n" + >+ " public void run() {\n" + >+ " s23.toString();\n" + >+ " }\n" + >+ " }.run();\n" + >+ " }\n" + >+ "}\n", >+ >+ }, >+ null, /* classLibs */ >+ customOptions, >+ "----------\n" + >+ "1. ERROR in X.java (at line 7)\n" + >+ " if (s1 != null)\n" + >+ " ^^\n" + >+ "Redundant null check: The variable s1 cannot be null at this location\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 17)\n" + >+ " s3.toString();\n" + >+ " ^^\n" + >+ "Potential null pointer access: The variable s3 may be null at this location\n" + >+ "----------\n" + >+ "3. ERROR in X.java (at line 26)\n" + >+ " s23.toString();\n" + >+ " ^^^\n" + >+ "Null pointer access: The variable s23 can only be null at this location\n" + >+ "----------\n", >+ "",/* expected output */ >+ "",/* expected error */ >+ JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); >+} >+// Bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop) >+// constructors >+public void testBug360328b() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR); >+ customOptions.put(CompilerOptions.OPTION_ReportRedundantNullCheck, CompilerOptions.ERROR); >+ runNegativeTest( >+ true, /* flushOutputDir */ >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " void print4() {\n" + >+ " final String s1 = \"\";\n" + >+ " for (int i=0; i<4; i++) {\n" + >+ " class R {\n" + >+ " public R() {\n" + >+ " if (s1 != null)\n" + >+ " s1.toString();\n" + >+ " }\n" + >+ " };\n" + >+ " new R();\n" + >+ " }\n" + >+ " }\n" + >+ " void print16(boolean b) {\n" + >+ " final String s3 = b ? null : \"\";\n" + >+ " int i=0; while (i++<16) {\n" + >+ " class R {\n" + >+ " public R() {\n" + >+ " s3.toString();\n" + >+ " }\n" + >+ " };\n" + >+ " new R();\n" + >+ " };\n" + >+ " }\n" + >+ " void print23() {\n" + >+ " final String s23 = null;\n" + >+ " for (int i=0; i<23; i++) {\n" + >+ " class R {\n" + >+ " public R() {\n" + >+ " s23.toString();\n" + >+ " }\n" + >+ " };\n" + >+ " new R();\n" + >+ " };\n" + >+ " }\n" + >+ "}\n", >+ >+ }, >+ null, /* classLibs */ >+ customOptions, >+ "----------\n" + >+ "1. ERROR in X.java (at line 7)\n" + >+ " if (s1 != null)\n" + >+ " ^^\n" + >+ "Redundant null check: The variable s1 cannot be null at this location\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 19)\n" + >+ " s3.toString();\n" + >+ " ^^\n" + >+ "Potential null pointer access: The variable s3 may be null at this location\n" + >+ "----------\n" + >+ "3. ERROR in X.java (at line 30)\n" + >+ " s23.toString();\n" + >+ " ^^^\n" + >+ "Null pointer access: The variable s23 can only be null at this location\n" + >+ "----------\n", >+ "",/* expected output */ >+ "",/* expected error */ >+ JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); >+} >+// Bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop) >+// initializers >+public void testBug360328c() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR); >+ customOptions.put(CompilerOptions.OPTION_ReportRedundantNullCheck, CompilerOptions.ERROR); >+ customOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.IGNORE); >+ runNegativeTest( >+ true, /* flushOutputDir */ >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " void print4() {\n" + >+ " final String s1 = \"\";\n" + >+ " for (int i=0; i<4; i++) {\n" + >+ " class R {\n" + >+ " String s1R;\n" + >+ " {\n" + >+ " if (s1 != null)\n" + >+ " s1R = s1;\n" + >+ " }\n" + >+ " };\n" + >+ " new R();\n" + >+ " }\n" + >+ " }\n" + >+ " void print16(boolean b) {\n" + >+ " final String s3 = b ? null : \"\";\n" + >+ " for (int i=0; i<16; i++) {\n" + >+ " class R {\n" + >+ " String s3R = s3.toString();\n" + >+ " };\n" + >+ " new R();\n" + >+ " };\n" + >+ " }\n" + >+ " void print23() {\n" + >+ " final String s23 = null;\n" + >+ " for (int i=0; i<23; i++) {\n" + >+ " class R {\n" + >+ " String s23R;\n" + >+ " {\n" + >+ " s23R = s23.toString();\n" + >+ " }\n" + >+ " };\n" + >+ " new R();\n" + >+ " };\n" + >+ " }\n" + >+ "}\n", >+ >+ }, >+ null, /* classLibs */ >+ customOptions, >+ "----------\n" + >+ "1. ERROR in X.java (at line 8)\n" + >+ " if (s1 != null)\n" + >+ " ^^\n" + >+ "Redundant null check: The variable s1 cannot be null at this location\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 19)\n" + >+ " String s3R = s3.toString();\n" + >+ " ^^\n" + >+ "Potential null pointer access: The variable s3 may be null at this location\n" + >+ "----------\n" + >+ "3. ERROR in X.java (at line 30)\n" + >+ " s23R = s23.toString();\n" + >+ " ^^^\n" + >+ "Null pointer access: The variable s23 can only be null at this location\n" + >+ "----------\n", >+ "",/* expected output */ >+ "",/* expected error */ >+ JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); >+} >+// Bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop) >+// try-finally instead of loop >+public void testBug360328d() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR); >+ customOptions.put(CompilerOptions.OPTION_ReportRedundantNullCheck, CompilerOptions.ERROR); >+ runNegativeTest( >+ true, /* flushOutputDir */ >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " void print4() {\n" + >+ " final String s1 = \"\";\n" + >+ " try { } finally {\n" + >+ " new Runnable() {\n" + >+ " public void run() {\n" + >+ " if (s1 != null)\n" + >+ " s1.toString();\n" + >+ " }\n" + >+ " }.run();\n" + >+ " }\n" + >+ " }\n" + >+ " void print16(boolean b) {\n" + >+ " final String s3 = b ? null : \"\";\n" + >+ " try { } finally {\n" + >+ " new Runnable() {\n" + >+ " public void run() {\n" + >+ " s3.toString();\n" + >+ " }\n" + >+ " }.run();\n" + >+ " }\n" + >+ " }\n" + >+ " void print23() {\n" + >+ " final String s23 = null;\n" + >+ " try { } finally {\n" + >+ " new Runnable() {\n" + >+ " public void run() {\n" + >+ " s23.toString();\n" + >+ " }\n" + >+ " }.run();\n" + >+ " }\n" + >+ " }\n" + >+ "}\n", >+ >+ }, >+ null, /* classLibs */ >+ customOptions, >+ "----------\n" + >+ "1. ERROR in X.java (at line 7)\n" + >+ " if (s1 != null)\n" + >+ " ^^\n" + >+ "Redundant null check: The variable s1 cannot be null at this location\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 18)\n" + >+ " s3.toString();\n" + >+ " ^^\n" + >+ "Potential null pointer access: The variable s3 may be null at this location\n" + >+ "----------\n" + >+ "3. ERROR in X.java (at line 28)\n" + >+ " s23.toString();\n" + >+ " ^^^\n" + >+ "Null pointer access: The variable s23 can only be null at this location\n" + >+ "----------\n", >+ "",/* expected output */ >+ "",/* expected error */ >+ JavacTestOptions.Excuse.EclipseWarningConfiguredAsError); >+} > } >\ No newline at end of file >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ProblemTypeAndMethodTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ProblemTypeAndMethodTest.java >index a551aa0..3b4db37 100644 >--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ProblemTypeAndMethodTest.java >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ProblemTypeAndMethodTest.java >@@ -7076,4 +7076,116 @@ > compilerOptions /* custom options */ > ); > } >+ >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=354502 >+// Anonymous class instantiation of a non-static member type, method can't be static >+public void test354502() { >+ if (this.complianceLevel < ClassFileConstants.JDK1_5) >+ return; >+ Map compilerOptions = getCompilerOptions(); >+ compilerOptions.put(CompilerOptions.OPTION_ReportMethodCanBeStatic, CompilerOptions.ERROR); >+ compilerOptions.put(CompilerOptions.OPTION_ReportMethodCanBePotentiallyStatic, CompilerOptions.ERROR); >+ compilerOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.IGNORE); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " public abstract class Abstract{}\n" + >+ " public static abstract class Abstract2{}\n" + >+ " private void method1() {\n" + // don't warn >+ " new Abstract() {};\n" + >+ " }\n" + >+ " private void method2() {\n" + // warn >+ " new Abstract2() {};\n" + >+ " }\n" + >+ "}" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 7)\n" + >+ " private void method2() {\n" + >+ " ^^^^^^^^^\n" + >+ "The method method2() from the type X can be declared as static\n" + >+ "----------\n", >+ null /* no extra class libraries */, >+ true /* flush output directory */, >+ compilerOptions /* custom options */ >+ ); >+} >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=360164 >+public void test360164() { >+ if (this.complianceLevel < ClassFileConstants.JDK1_5) return; >+ this.runConformTest( >+ new String[] { >+ "p/B.java", >+ "package p;\n" + >+ "\n" + >+ "public abstract class B<K,V> {\n" + >+ " protected abstract V foo(K element);\n" + >+ "}\n", >+ "p/C.java", >+ "package p;\n" + >+ "public class C {\n" + >+ "}\n", >+ "p/D.java", >+ "package p;\n" + >+ "public class D extends E {\n" + >+ "}\n", >+ "p/E.java", >+ "package p;\n" + >+ "public abstract class E implements I {\n" + >+ "}\n", >+ "p/I.java", >+ "package p;\n" + >+ "public interface I {\n" + >+ "}\n", >+ "p/X.java", >+ "package p;\n" + >+ "public class X {\n" + >+ " private final class A extends B<C,D>{\n" + >+ " @Override\n" + >+ " protected D foo(C c) {\n" + >+ " return null;\n" + >+ " }\n" + >+ " }\n" + >+ "}\n", >+ }, >+ ""); >+ >+ // delete binary file I (i.e. simulate removing it from classpath for subsequent compile) >+ Util.delete(new File(OUTPUT_DIR, "p" + File.separator + "I.class")); >+ >+ runNegativeTest( >+ // test directory preparation >+ false /* do not flush output directory */, >+ new String[] { /* test files */ >+ "p/X.java", >+ "package p;\n" + >+ "public class X {\n" + >+ " private final class A extends B<C,D>{\n" + >+ " @Override\n" + >+ " protected D foo(C c) {\n" + >+ " Zork z;\n" + >+ " return null;\n" + >+ " }\n" + >+ " }\n" + >+ "}\n", >+ }, >+ // compiler options >+ null /* no class libraries */, >+ null /* no custom options */, >+ // compiler results >+ "----------\n" + >+ "1. WARNING in p\\X.java (at line 3)\n" + >+ " private final class A extends B<C,D>{\n" + >+ " ^\n" + >+ "The type X.A is never used locally\n" + >+ "----------\n" + >+ "2. ERROR in p\\X.java (at line 6)\n" + >+ " Zork z;\n" + >+ " ^^^^\n" + >+ "Zork cannot be resolved to a type\n" + >+ "----------\n", >+ // javac options >+ JavacTestOptions.SKIP_UNTIL_FRAMEWORK_FIX /* javac test options */); >+} > } >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java >new file mode 100644 >index 0000000..beeb07b >--- /dev/null >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java >@@ -0,0 +1,3713 @@ >+/******************************************************************************* >+ * Copyright (c) 2011, 2012 GK Software AG 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: >+ * Stephan Herrmann - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.core.tests.compiler.regression; >+ >+import java.io.IOException; >+import java.net.URL; >+import java.util.Map; >+ >+import junit.framework.Test; >+ >+import org.eclipse.core.runtime.FileLocator; >+import org.eclipse.core.runtime.Path; >+import org.eclipse.core.runtime.Platform; >+import org.eclipse.jdt.core.JavaCore; >+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; >+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; >+ >+public class ResourceLeakTests extends AbstractRegressionTest { >+ >+static { >+// TESTS_NAMES = new String[] { "test066"}; >+// TESTS_NUMBERS = new int[] { 50 }; >+// TESTS_RANGE = new int[] { 11, -1 }; >+} >+public ResourceLeakTests(String name) { >+ super(name); >+} >+public static Test suite() { >+ return buildAllCompliancesTestSuite(ResourceLeakTests.class); >+} >+ >+void runTestsExpectingErrorsOnlyIn17(String[] testFiles, String errorsIn17, Map options) { >+ if (this.complianceLevel >= ClassFileConstants.JDK1_7) >+ runNegativeTest(testFiles, errorsIn17, null, true, options); >+ else >+ runConformTest(testFiles, "", null, true, null, options, null); >+} >+ >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// a method uses an AutoCloseable without ever closing it. >+public void test056() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " FileReader fileReader = new FileReader(file);\n" + >+// not invoking any methods on FileReader, try to avoid necessary call to superclass() in the compiler >+// " char[] in = new char[50];\n" + >+// " fileReader.read(in);\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " new X().foo();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 7)\n" + >+ " FileReader fileReader = new FileReader(file);\n" + >+ " ^^^^^^^^^^\n" + >+ "Resource leak: 'fileReader' is never closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// a method uses an AutoCloseable and closes it but not protected by t-w-r nor regular try-finally >+public void test056a() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR); >+ runTestsExpectingErrorsOnlyIn17( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " FileReader fileReader = new FileReader(file);\n" + >+ " char[] in = new char[50];\n" + >+ " fileReader.read(in);\n" + >+ " fileReader.close();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 7)\n" + >+ " FileReader fileReader = new FileReader(file);\n" + >+ " ^^^^^^^^^^\n" + >+ "Resource 'fileReader' should be managed by try-with-resource\n" + >+ "----------\n", >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// a method uses an AutoCloseable and closes it properly in a finally block >+public void test056b() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " FileReader fileReader = new FileReader(file);\n" + >+ " try {\n" + >+ " char[] in = new char[50];\n" + >+ " fileReader.read(in);\n" + >+ " } finally {\n" + >+ " fileReader.close();\n" + >+ " }\n" + >+ " }\n" + >+ " public static void main(String[] args) {\n" + >+ " try {\n" + >+ " new X().foo();\n" + >+ " } catch (IOException ioex) {\n" + >+ " System.out.println(\"caught\");\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "caught", /*output*/ >+ null/*classLibs*/, >+ true/*shouldFlush*/, >+ null/*vmargs*/, >+ options, >+ null/*requestor*/); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// a method uses an AutoCloseable properly within try-with-resources. >+public void test056c() { >+ if (this.complianceLevel < ClassFileConstants.JDK1_7) return; // t-w-r used >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING); >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " try (FileReader fileReader = new FileReader(file)) {\n" + >+ " char[] in = new char[50];\n" + >+ " fileReader.read(in);\n" + >+ " }\n" + >+ " }\n" + >+ " public static void main(String[] args) {\n" + >+ " try {\n" + >+ " new X().foo();\n" + >+ " } catch (IOException ioex) {\n" + >+ " System.out.println(\"caught\");\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "caught", /*output*/ >+ null/*classLibs*/, >+ true/*shouldFlush*/, >+ null/*vmargs*/, >+ options, >+ null/*requestor*/); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// a method uses two AutoCloseables (testing independent analysis) >+//- one closeable may be unclosed at a conditional return >+//- the other is only conditionally closed >+public void test056d() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo(boolean flag1, boolean flag2) throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " char[] in = new char[50];\n" + >+ " FileReader fileReader1 = new FileReader(file);\n" + >+ " fileReader1.read(in);\n" + >+ " FileReader fileReader2 = new FileReader(file);\n" + >+ " fileReader2.read(in);\n" + >+ " if (flag1) {\n" + >+ " fileReader2.close();\n" + >+ " return;\n" + >+ " } else if (flag2) {\n" + >+ " fileReader2.close();\n" + >+ " }\n" + >+ " fileReader1.close();\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " new X().foo(false, true);\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. WARNING in X.java (at line 10)\n" + >+ " FileReader fileReader2 = new FileReader(file);\n" + >+ " ^^^^^^^^^^^\n" + >+ "Potential resource leak: 'fileReader2' may not be closed\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 14)\n" + >+ " return;\n" + >+ " ^^^^^^^\n" + >+ "Resource leak: 'fileReader1' is not closed at this location\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// a method uses two AutoCloseables (testing independent analysis) >+//- one closeable may be unclosed at a conditional return >+//- the other is only conditionally closed >+public void test056d_suppress() { >+ if (this.complianceLevel < ClassFileConstants.JDK1_5) return; // annotations used >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING); >+ options.put(CompilerOptions.OPTION_SuppressOptionalErrors, CompilerOptions.ENABLED); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo(boolean flag1, boolean flag2) throws IOException {\n" + >+ " @SuppressWarnings(\"resource\") File file = new File(\"somefile\"); // unnecessary suppress\n" + >+ " char[] in = new char[50];\n" + >+ " FileReader fileReader1 = new FileReader(file);\n" + >+ " fileReader1.read(in);\n" + >+ " @SuppressWarnings(\"resource\") FileReader fileReader2 = new FileReader(file); // useful suppress\n" + >+ " fileReader2.read(in);\n" + >+ " if (flag1) {\n" + >+ " fileReader2.close();\n" + >+ " return; // not suppressed\n" + >+ " } else if (flag2) {\n" + >+ " fileReader2.close();\n" + >+ " }\n" + >+ " fileReader1.close();\n" + >+ " }\n" + >+ " @SuppressWarnings(\"resource\") // useful suppress\n" + >+ " void bar() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " FileReader fileReader = new FileReader(file);\n" + >+ " char[] in = new char[50];\n" + >+ " fileReader.read(in);\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " new X().foo(false, true);\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. WARNING in X.java (at line 6)\n" + >+ " @SuppressWarnings(\"resource\") File file = new File(\"somefile\"); // unnecessary suppress\n" + >+ " ^^^^^^^^^^\n" + >+ "Unnecessary @SuppressWarnings(\"resource\")\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 14)\n" + >+ " return; // not suppressed\n" + >+ " ^^^^^^^\n" + >+ "Resource leak: 'fileReader1' is not closed at this location\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// Bug 362332 - Only report potential leak when closeable not created in the local scope >+// one method returns an AutoCleasble, a second method uses this object without ever closing it. >+public void test056e() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " FileReader getReader(String filename) throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " FileReader fileReader = new FileReader(file);\n" + >+ " return fileReader;\n" + // don't complain here, pass responsibility to caller >+ " }\n" + >+ " void foo() throws IOException {\n" + >+ " FileReader reader = getReader(\"somefile\");\n" + >+ " char[] in = new char[50];\n" + >+ " reader.read(in);\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " new X().foo();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 11)\n" + >+ " FileReader reader = getReader(\"somefile\");\n" + >+ " ^^^^^^\n" + >+ "Potential resource leak: \'reader\' may not be closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// a method explicitly closes its AutoCloseable rather than using t-w-r >+public void test056f() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING); >+ options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR); >+ runTestsExpectingErrorsOnlyIn17( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " FileReader fileReader = null;\n" + >+ " try {\n" + >+ " fileReader = new FileReader(file);\n" + >+ " char[] in = new char[50];\n" + >+ " fileReader.read(in);\n" + >+ " } finally {\n" + >+ " fileReader.close();\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 7)\n" + >+ " FileReader fileReader = null;\n" + >+ " ^^^^^^^^^^\n" + >+ "Resource 'fileReader' should be managed by try-with-resource\n" + >+ "----------\n", >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// an AutoCloseable local is re-assigned >+public void test056g() { >+ Map options = getCompilerOptions(); >+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING); >+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " FileReader fileReader = new FileReader(file);\n" + >+ " char[] in = new char[50];\n" + >+ " fileReader.read(in);\n" + >+ " fileReader = new FileReader(file);\n" + >+ " fileReader.read(in);\n" + >+ " fileReader.close();\n" + >+ " fileReader = null;\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " new X().foo();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 10)\n" + >+ " fileReader = new FileReader(file);\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Resource leak: 'fileReader' is not closed at this location\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// an AutoCloseable local is re-assigned after null-assigned >+public void test056g2() { >+ Map options = getCompilerOptions(); >+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING); >+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " FileReader fileReader = new FileReader(file);\n" + >+ " char[] in = new char[50];\n" + >+ " fileReader.read(in);\n" + >+ " fileReader = null;\n" + >+ " fileReader = new FileReader(file);\n" + // don't complain again, fileReader is null, so nothing can leak here >+ " fileReader.read(in);\n" + >+ " fileReader.close();\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " new X().foo();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 10)\n" + >+ " fileReader = null;\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Resource leak: 'fileReader' is not closed at this location\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// two AutoCloseables at different nesting levels (anonymous local type) >+public void test056h() { >+ Map options = getCompilerOptions(); >+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING); >+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " final File file = new File(\"somefile\");\n" + >+ " final FileReader fileReader = new FileReader(file);\n" + >+ " char[] in = new char[50];\n" + >+ " fileReader.read(in);\n" + >+ " new Runnable() {\n public void run() {\n" + >+ " try {\n" + >+ " fileReader.close();\n" + >+ " FileReader localReader = new FileReader(file);\n" + >+ " } catch (IOException ex) { /* nop */ }\n" + >+ " }}.run();\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " new X().foo();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. WARNING in X.java (at line 7)\n" + >+ " final FileReader fileReader = new FileReader(file);\n" + >+ " ^^^^^^^^^^\n" + >+ "Potential resource leak: 'fileReader' may not be closed\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 14)\n" + >+ " FileReader localReader = new FileReader(file);\n" + >+ " ^^^^^^^^^^^\n" + >+ "Resource leak: 'localReader' is never closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// three AutoCloseables in different blocks of the same method >+public void test056i() { >+ Map options = getCompilerOptions(); >+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING); >+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo(boolean f1, boolean f2) throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " if (f1) {\n" + >+ " FileReader fileReader = new FileReader(file); // err: not closed\n" + >+ " char[] in = new char[50];\n" + >+ " fileReader.read(in);\n" + >+ " while (true) {\n" + >+ " FileReader loopReader = new FileReader(file); // don't warn, properly closed\n" + >+ " loopReader.close();" + >+ " break;\n" + >+ " }\n" + >+ " } else {\n" + >+ " FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" + >+ " if (f2)\n" + >+ " fileReader.close();\n" + >+ " }\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " new X().foo(true, true);\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 8)\n" + >+ " FileReader fileReader = new FileReader(file); // err: not closed\n" + >+ " ^^^^^^^^^^\n" + >+ "Resource leak: 'fileReader' is never closed\n" + >+ "----------\n" + >+ "2. WARNING in X.java (at line 16)\n" + >+ " FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" + >+ " ^^^^^^^^^^\n" + >+ "Potential resource leak: 'fileReader' may not be closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// three AutoCloseables in different blocks of the same method - problems ignored >+public void test056i_ignore() { >+ Map options = getCompilerOptions(); >+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.IGNORE); >+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.IGNORE); >+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE); >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo(boolean f1, boolean f2) throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " if (f1) {\n" + >+ " FileReader fileReader = new FileReader(file); // err: not closed\n" + >+ " char[] in = new char[50];\n" + >+ " fileReader.read(in);\n" + >+ " while (true) {\n" + >+ " FileReader loopReader = new FileReader(file); // don't warn, properly closed\n" + >+ " loopReader.close();" + >+ " break;\n" + >+ " }\n" + >+ " } else {\n" + >+ " FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" + >+ " if (f2)\n" + >+ " fileReader.close();\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "", >+ null, >+ true, >+ null, >+ options, >+ null); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// three AutoCloseables in different blocks of the same method >+public void test056i2() { >+ Map options = getCompilerOptions(); >+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo(boolean f1, boolean f2) throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " if (f1) {\n" + >+ " FileReader fileReader = new FileReader(file); // properly closed\n" + >+ " char[] in = new char[50];\n" + >+ " fileReader.read(in);\n" + >+ " while (true) {\n" + >+ " fileReader.close();\n" + >+ " FileReader loopReader = new FileReader(file); // don't warn, properly closed\n" + >+ " loopReader.close();\n" + >+ " break;\n" + >+ " }\n" + >+ " } else {\n" + >+ " FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" + >+ " if (f2)\n" + >+ " fileReader.close();\n" + >+ " }\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " new X().foo(true, true);\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 18)\n" + >+ " FileReader fileReader = new FileReader(file); // warn: not closed on all paths\n" + >+ " ^^^^^^^^^^\n" + >+ "Potential resource leak: 'fileReader' may not be closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// a method uses an AutoCloseable without closing it locally but passing as arg to another method >+public void test056j() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " FileReader fileReader = new FileReader(file);\n" + >+ " read(fileReader);\n" + >+ " }\n" + >+ " void read(FileReader reader) { }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " new X().foo();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 7)\n" + >+ " FileReader fileReader = new FileReader(file);\n" + >+ " ^^^^^^^^^^\n" + >+ "Potential resource leak: 'fileReader' may not be closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// a method uses an AutoCloseable without closing it locally but passing as arg to another method >+public void test056jconditional() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo(boolean b) throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " FileReader fileReader = new FileReader(file);\n" + >+ " synchronized (b ? this : new X()) {\n" + >+ " new ReadDelegator(fileReader);\n" + >+ " }\n" + >+ " }\n" + >+ " class ReadDelegator { ReadDelegator(FileReader reader) { } }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " new X().foo(true);\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 7)\n" + >+ " FileReader fileReader = new FileReader(file);\n" + >+ " ^^^^^^^^^^\n" + >+ "Potential resource leak: 'fileReader' may not be closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// many locals, some are AutoCloseable. >+// Unfortunately analysis cannot respect how exception exits may affect ra3 and rb3, >+// doing so would create false positives. >+public void test056k() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING); >+ options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR); >+ String expectedProblems = this.complianceLevel < ClassFileConstants.JDK1_7 ? >+ "----------\n" + >+ "1. ERROR in X.java (at line 15)\n" + >+ " ra2 = new FileReader(file);\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Resource leak: \'ra2\' is never closed\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 28)\n" + >+ " rb2 = new FileReader(file);\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Resource leak: \'rb2\' is never closed\n" + >+ "----------\n" >+ : >+ "----------\n" + >+ "1. ERROR in X.java (at line 12)\n" + >+ " FileReader ra1 = null, ra2 = null;\n" + >+ " ^^^\n" + >+ "Resource 'ra1' should be managed by try-with-resource\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 15)\n" + >+ " ra2 = new FileReader(file);\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Resource leak: 'ra2' is never closed\n" + >+ "----------\n" + >+ "3. ERROR in X.java (at line 16)\n" + >+ " FileReader ra3 = new FileReader(file);\n" + >+ " ^^^\n" + >+ "Resource 'ra3' should be managed by try-with-resource\n" + >+ "----------\n" + >+ "4. ERROR in X.java (at line 25)\n" + >+ " FileReader rb1 = null, rb2 = null;\n" + >+ " ^^^\n" + >+ "Resource 'rb1' should be managed by try-with-resource\n" + >+ "----------\n" + >+ "5. ERROR in X.java (at line 28)\n" + >+ " rb2 = new FileReader(file);\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Resource leak: 'rb2' is never closed\n" + >+ "----------\n" + >+ "6. ERROR in X.java (at line 29)\n" + >+ " FileReader rb3 = new FileReader(file);\n" + >+ " ^^^\n" + >+ "Resource 'rb3' should be managed by try-with-resource\n" + >+ "----------\n"; >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " int i01, i02, i03, i04, i05, i06, i07, i08, i09,\n" + >+ " i11, i12, i13, i14, i15, i16, i17, i18, i19,\n" + >+ " i21, i22, i23, i24, i25, i26, i27, i28, i29,\n" + >+ " i31, i32, i33, i34, i35, i36, i37, i38, i39,\n" + >+ " i41, i42, i43, i44, i45, i46, i47, i48, i49;\n" + >+ " File file = new File(\"somefile\");\n" + >+ " FileReader ra1 = null, ra2 = null;\n" + >+ " try {\n" + >+ " ra1 = new FileReader(file);\n" + >+ " ra2 = new FileReader(file);\n" + >+ " FileReader ra3 = new FileReader(file);\n" + >+ " char[] in = new char[50];\n" + >+ " ra1.read(in);\n" + >+ " ra2.read(in);\n" + >+ " ra3.close();\n" + >+ " } finally {\n" + >+ " ra1.close();\n" + >+ " }\n" + >+ " int i51, i52, i53, i54, i55, i56, i57, i58, i59, i60;\n" + // beyond this point locals are analyzed using extraBits >+ " FileReader rb1 = null, rb2 = null;\n" + >+ " try {\n" + >+ " rb1 = new FileReader(file);\n" + >+ " rb2 = new FileReader(file);\n" + >+ " FileReader rb3 = new FileReader(file);\n" + >+ " char[] in = new char[50];\n" + >+ " rb1.read(in);\n" + >+ " rb2.read(in);\n" + >+ " rb3.close();\n" + >+ " } finally {\n" + >+ " rb1.close();\n" + >+ " }\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " new X().foo();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ expectedProblems, >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// various non-problems >+public void test056l() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR); >+ String expectedProblems = this.complianceLevel >= ClassFileConstants.JDK1_7 ? >+ "----------\n" + >+ "1. ERROR in X.java (at line 8)\n" + >+ " FileReader fileReader = getReader();\n" + >+ " ^^^^^^^^^^\n" + >+ "Resource 'fileReader' should be managed by try-with-resource\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 11)\n" + >+ " FileReader r3 = getReader();\n" + >+ " ^^\n" + >+ "Resource 'r3' should be managed by try-with-resource\n" + >+ "----------\n" + >+ "3. ERROR in X.java (at line 24)\n" + >+ " FileReader r2 = new FileReader(new File(\"inexist\")); // only potential problem: ctor X below might close r2\n" + >+ " ^^\n" + >+ "Potential resource leak: 'r2' may not be closed\n" + >+ "----------\n" + >+ "4. ERROR in X.java (at line 25)\n" + >+ " new X(r2).foo(new FileReader(new File(\"notthere\"))); // potential problem: foo may/may not close the new FileReader\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Potential resource leak: \'<unassigned Closeable value>\' may not be closed\n" + >+ "----------\n" >+ : >+ "----------\n" + >+ "1. ERROR in X.java (at line 24)\n" + >+ " FileReader r2 = new FileReader(new File(\"inexist\")); // only potential problem: ctor X below might close r2\n" + >+ " ^^\n" + >+ "Potential resource leak: 'r2' may not be closed\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 25)\n" + >+ " new X(r2).foo(new FileReader(new File(\"notthere\"))); // potential problem: foo may/may not close the new FileReader\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Potential resource leak: \'<unassigned Closeable value>\' may not be closed\n" + >+ "----------\n"; >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " X(FileReader r0) {}\n" + // don't complain against argument >+ " FileReader getReader() { return null; }\n" + >+ " void foo(FileReader r1) throws IOException {\n" + >+ " FileReader fileReader = getReader();\n" + >+ " if (fileReader == null)\n" + >+ " return;\n" + // don't complain, resource is actually null >+ " FileReader r3 = getReader();\n" + >+ " if (r3 == null)\n" + >+ " r3 = new FileReader(new File(\"absent\"));\n" + // don't complain, previous resource is actually null >+ " try {\n" + >+ " char[] in = new char[50];\n" + >+ " fileReader.read(in);\n" + >+ " r1.read(in);\n" + >+ " } finally {\n" + >+ " fileReader.close();\n" + >+ " r3.close();\n" + // the effect of this close() call might be spoiled by exception in fileReader.close() above, but we ignore exception exits in the analysis >+ " }\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " FileReader r2 = new FileReader(new File(\"inexist\")); // only potential problem: ctor X below might close r2\n" + >+ " new X(r2).foo(new FileReader(new File(\"notthere\"))); // potential problem: foo may/may not close the new FileReader\n" + >+ " }\n" + >+ "}\n" >+ }, >+ expectedProblems, >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// nested try with early exit >+public void test056m() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() {\n" + >+ " File file = new File(\"somefile\");" + >+ " try {\n" + >+ " FileReader fileReader = new FileReader(file);\n" + >+ " try {\n" + >+ " char[] in = new char[50];\n" + >+ " if (fileReader.read(in)==0)\n" + >+ " return;\n" + >+ " } finally {\n" + >+ " fileReader.close();\n" + >+ " }\n" + >+ " } catch (IOException e) {\n" + >+ " System.out.println(\"caught\");\n" + >+ " }\n" + >+ " }\n" + >+ " public static void main(String[] args) {\n" + >+ " new X().foo();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "caught", /*output*/ >+ null/*classLibs*/, >+ true/*shouldFlush*/, >+ null/*vmargs*/, >+ options, >+ null/*requestor*/); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// nested try should not interfere with earlier analysis. >+public void test056n() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "import java.io.FileNotFoundException;\n" + >+ "public class X {\n" + >+ " void foo(File someFile, char[] buf) throws IOException {\n" + >+ " FileReader fr1 = new FileReader(someFile);\n" + >+ " try {\n" + >+ " fr1.read(buf);\n" + >+ " } finally {\n" + >+ " fr1.close();\n" + >+ " }\n" + >+ " try {\n" + >+ " FileReader fr3 = new FileReader(someFile);\n" + >+ " try {\n" + >+ " } finally {\n" + >+ " fr3.close();\n" + >+ " }\n" + >+ " } catch (IOException e) {\n" + >+ " }\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " try {\n" + >+ " new X().foo(new File(\"missing\"), new char[100]);\n" + >+ " } catch (FileNotFoundException e) {\n" + >+ " System.out.println(\"caught\");\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "caught", /*output*/ >+ null/*classLibs*/, >+ true/*shouldFlush*/, >+ null/*vmargs*/, >+ options, >+ null/*requestor*/); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// if close is guarded by null check this should still be recognized as definitely closed >+public void test056o() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "import java.io.FileNotFoundException;\n" + >+ "public class X {\n" + >+ " void foo(File someFile, char[] buf) throws IOException {\n" + >+ " FileReader fr1 = null;\n" + >+ " try {\n" + >+ " fr1 = new FileReader(someFile);" + >+ " fr1.read(buf);\n" + >+ " } finally {\n" + >+ " if (fr1 != null)\n" + >+ " try {\n" + >+ " fr1.close();\n" + >+ " } catch (IOException e) { /*do nothing*/ }\n" + >+ " }\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " try {\n" + >+ " new X().foo(new File(\"missing\"), new char[100]);\n" + >+ " } catch (FileNotFoundException e) {\n" + >+ " System.out.println(\"caught\");\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "caught", /*output*/ >+ null/*classLibs*/, >+ true/*shouldFlush*/, >+ null/*vmargs*/, >+ options, >+ null/*requestor*/); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// Bug 362332 - Only report potential leak when closeable not created in the local scope >+// a method uses an AutoCloseable without ever closing it, type from a type variable >+public void test056p() { >+ if (this.complianceLevel < ClassFileConstants.JDK1_5) return; // generics used >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.Reader;\n" + >+ "import java.io.IOException;\n" + >+ "public abstract class X <T extends Reader> {\n" + >+ " void foo() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " T fileReader = newReader(file);\n" + >+ " char[] in = new char[50];\n" + >+ " fileReader.read(in);\n" + >+ " }\n" + >+ " abstract T newReader(File file) throws IOException;\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " new X<FileReader>() {\n" + >+ " FileReader newReader(File f) throws IOException { return new FileReader(f); }\n" + >+ " }.foo();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 8)\n" + >+ " T fileReader = newReader(file);\n" + >+ " ^^^^^^^^^^\n" + >+ "Potential resource leak: \'fileReader\' may not be closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// closed in dead code >+public void test056q() { >+ Map options = getCompilerOptions(); >+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING); >+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " FileReader fileReader = new FileReader(file);\n" + >+ " char[] in = new char[50];\n" + >+ " fileReader.read(in);\n" + >+ " if (2*2 == 4)\n" + >+ " return;\n" + >+ " fileReader.close();\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " new X().foo();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 7)\n" + >+ " FileReader fileReader = new FileReader(file);\n" + >+ " ^^^^^^^^^^\n" + >+ "Resource leak: 'fileReader' is never closed\n" + >+ "----------\n" + >+ "2. WARNING in X.java (at line 10)\n" + >+ " if (2*2 == 4)\n" + >+ " ^^^^^^^^\n" + >+ "Comparing identical expressions\n" + >+ "----------\n" + >+ "3. WARNING in X.java (at line 12)\n" + >+ " fileReader.close();\n" + >+ " ^^^^^^^^^^^^^^^^^^\n" + >+ "Dead code\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// properly closed, dead code in between >+public void test056r() { >+ Map options = getCompilerOptions(); >+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING); >+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE); >+ options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " FileReader fr = new FileReader(file);\n" + >+ " Object b = null;\n" + >+ " fr.close();\n" + >+ " if (b != null) {\n" + >+ " fr = new FileReader(file);\n" + >+ " return;\n" + >+ " } else {\n" + >+ " System.out.print(42);\n" + >+ " }\n" + >+ " return; // Should not complain about fr\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " new X().foo();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 10)\n" + >+ " if (b != null) {\n" + >+ " fr = new FileReader(file);\n" + >+ " return;\n" + >+ " } else {\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Dead code\n" + >+ "----------\n" + >+ "2. WARNING in X.java (at line 13)\n" + >+ " } else {\n" + >+ " System.out.print(42);\n" + >+ " }\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Statement unnecessarily nested within else clause. The corresponding then clause does not complete normally\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// resource inside t-w-r is re-assigned, shouldn't even record an errorLocation >+public void test056s() { >+ if (this.complianceLevel < ClassFileConstants.JDK1_7) return; // t-w-r used >+ Map options = getCompilerOptions(); >+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING); >+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.IGNORE); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " try (FileReader fileReader = new FileReader(file);) {\n" + >+ " char[] in = new char[50];\n" + >+ " fileReader.read(in);\n" + >+ " fileReader = new FileReader(file); // debug here\n" + >+ " fileReader.read(in);\n" + >+ " }\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " new X().foo();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 10)\n" + >+ " fileReader = new FileReader(file); // debug here\n" + >+ " ^^^^^^^^^^\n" + >+ "The resource fileReader of a try-with-resources statement cannot be assigned\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// resource is closed, dead code follows >+public void test056t() { >+ Map options = getCompilerOptions(); >+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING); >+ options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo31() throws IOException {\n" + >+ " FileReader reader = new FileReader(\"file\"); //warning\n" + >+ " if (reader != null) {\n" + >+ " reader.close();\n" + >+ " } else {\n" + >+ " // nop\n" + >+ " }\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " new X().foo31();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 8)\n" + >+ " } else {\n" + >+ " // nop\n" + >+ " }\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Dead code\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// resource is reassigned within t-w-r with different resource >+// was initially broken due to https://bugs.eclipse.org/358827 >+public void test056u() { >+ if (this.complianceLevel < ClassFileConstants.JDK1_7) return; // t-w-r used >+ Map options = getCompilerOptions(); >+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING); >+ options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.FileReader;\n" + >+ "public class X {\n" + >+ " void foo() throws Exception {\n" + >+ " FileReader reader1 = new FileReader(\"file1\");\n" + >+ " FileReader reader2 = new FileReader(\"file2\");\n" + >+ " reader2 = reader1;// this disconnects reader 2\n" + >+ " try (FileReader reader3 = new FileReader(\"file3\")) {\n" + >+ " int ch;\n" + >+ " while ((ch = reader2.read()) != -1) {\n" + >+ " System.out.println(ch);\n" + >+ " reader1.read();\n" + >+ " }\n" + >+ " reader2 = reader1; // warning 1 regarding original reader1\n" + // this warning was missing >+ " reader2 = reader1; // warning 2 regarding original reader1\n" + >+ " } finally {\n" + >+ " if (reader2 != null) {\n" + >+ " reader2.close();\n" + >+ " } else {\n" + >+ " System.out.println();\n" + >+ " }\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 5)\n" + >+ " FileReader reader2 = new FileReader(\"file2\");\n" + >+ " ^^^^^^^\n" + >+ "Resource leak: 'reader2' is never closed\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 13)\n" + >+ " reader2 = reader1; // warning 1 regarding original reader1\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Resource leak: 'reader1' is not closed at this location\n" + >+ "----------\n" + >+ "3. ERROR in X.java (at line 14)\n" + >+ " reader2 = reader1; // warning 2 regarding original reader1\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Resource leak: 'reader1' is not closed at this location\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// scope-related pbs reported in https://bugs.eclipse.org/349326#c70 and https://bugs.eclipse.org/349326#c82 >+public void test056v() { >+ Map options = getCompilerOptions(); >+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING); >+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.WARNING); >+ options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR); >+ String expectedProblems = this.complianceLevel >= ClassFileConstants.JDK1_7 ? >+ "----------\n" + >+ "1. ERROR in X.java (at line 4)\n" + >+ " FileReader reader = new FileReader(\"file\");\n" + >+ " ^^^^^^\n" + >+ "Resource leak: 'reader' is never closed\n" + >+ "----------\n" + >+ "2. WARNING in X.java (at line 19)\n" + >+ " FileReader reader111 = new FileReader(\"file2\");\n" + >+ " ^^^^^^^^^\n" + >+ "Resource 'reader111' should be managed by try-with-resource\n" + >+ "----------\n" + >+ "3. ERROR in X.java (at line 42)\n" + >+ " return;\n" + >+ " ^^^^^^^\n" + >+ "Resource leak: 'reader2' is not closed at this location\n" + >+ "----------\n" >+ : >+ "----------\n" + >+ "1. ERROR in X.java (at line 4)\n" + >+ " FileReader reader = new FileReader(\"file\");\n" + >+ " ^^^^^^\n" + >+ "Resource leak: 'reader' is never closed\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 42)\n" + >+ " return;\n" + >+ " ^^^^^^^\n" + >+ "Resource leak: 'reader2' is not closed at this location\n" + >+ "----------\n"; >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.FileReader;\n" + >+ "public class X {\n" + >+ " boolean foo1() throws Exception {\n" + >+ " FileReader reader = new FileReader(\"file\");\n" + >+ " try {\n" + >+ " int ch;\n" + >+ " while ((ch = reader.read()) != -1) {\n" + >+ " System.out.println(ch);\n" + >+ " reader.read();\n" + >+ " }\n" + >+ " if (ch > 10) {\n" + >+ " return true;\n" + >+ " }\n" + >+ " return false;\n" + // return while resource from enclosing scope remains unclosed >+ " } finally {\n" + >+ " }\n" + >+ " }\n" + >+ " void foo111() throws Exception {\n" + >+ " FileReader reader111 = new FileReader(\"file2\");\n" + >+ " try {\n" + >+ " int ch;\n" + >+ " while ((ch = reader111.read()) != -1) {\n" + >+ " System.out.println(ch);\n" + >+ " reader111.read();\n" + >+ " }\n" + >+ " return;\n" + // this shouldn't spoil the warning "should be managed with t-w-r" >+ " } finally {\n" + >+ " if (reader111 != null) {\n" + >+ " reader111.close();\n" + >+ " }\n" + >+ " }\n" + >+ " }\n" + >+ " void foo2() throws Exception {\n" + >+ " FileReader reader2 = new FileReader(\"file\");\n" + >+ " try {\n" + >+ " int ch;\n" + >+ " while ((ch = reader2.read()) != -1) {\n" + >+ " System.out.println(ch);\n" + >+ " reader2.read();\n" + >+ " }\n" + >+ " if (ch > 10) {\n" + >+ " return;\n" + // potential leak >+ " }\n" + >+ " } finally {\n" + >+ " }\n" + >+ " reader2.close();\n" + // due to this close we don't say "never closed" >+ " }\n" + >+ "}\n" >+ }, >+ expectedProblems, >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// end of method is dead end, but before we have both a close() and an early return >+public void test056w() { >+ Map options = getCompilerOptions(); >+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING); >+ options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.FileReader;\n" + >+ "public class X {\n" + >+ " boolean foo1() throws Exception {\n" + >+ " FileReader reader = new FileReader(\"file\");\n" + >+ " try {\n" + >+ " int ch;\n" + >+ " while ((ch = reader.read()) != -1) {\n" + >+ " System.out.println(ch);\n" + >+ " reader.read();\n" + >+ " }\n" + >+ " if (ch > 10) {\n" + >+ " reader.close();\n" + >+ " return true;\n" + >+ " }\n" + >+ " return false;\n" + >+ " } finally {\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 15)\n" + >+ " return false;\n" + >+ " ^^^^^^^^^^^^^\n" + >+ "Resource leak: 'reader' is not closed at this location\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// different early exits, if no close seen report as definitely unclosed >+public void test056x() { >+ Map options = getCompilerOptions(); >+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING); >+ options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.FileReader;\n" + >+ "public class X {\n" + >+ " void foo31(boolean b) throws Exception {\n" + >+ " FileReader reader = new FileReader(\"file\");\n" + >+ " if (b) {\n" + >+ " reader.close();\n" + >+ " } else {\n" + >+ " return; // warning\n" + >+ " }\n" + >+ " }\n" + >+ " void foo32(boolean b) throws Exception {\n" + >+ " FileReader reader = new FileReader(\"file\"); // warn here\n" + >+ " return;\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 8)\n" + >+ " return; // warning\n" + >+ " ^^^^^^^\n" + >+ "Resource leak: 'reader' is not closed at this location\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 12)\n" + >+ " FileReader reader = new FileReader(\"file\"); // warn here\n" + >+ " ^^^^^^\n" + >+ "Resource leak: 'reader' is never closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// nested method passes the resource to outside code >+public void test056y() { >+ Map options = getCompilerOptions(); >+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.WARNING); >+ options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.FileReader;\n" + >+ "public class X {\n" + >+ " void foo31(boolean b) throws Exception {\n" + >+ " final FileReader reader31 = new FileReader(\"file\");\n" + >+ " new Runnable() {\n" + >+ " public void run() {\n" + >+ " foo18(reader31);\n" + >+ " }\n" + >+ " }.run();\n" + >+ " }\n" + >+ " void foo18(FileReader r18) {\n" + >+ " // could theoretically close r18;\n" + >+ " }\n" + >+ " abstract class ResourceProvider {\n" + >+ " abstract FileReader provide();" + >+ " }\n" + >+ " ResourceProvider provider;" + >+ " void foo23() throws Exception {\n" + >+ " final FileReader reader23 = new FileReader(\"file\");\n" + >+ " provider = new ResourceProvider() {\n" + >+ " public FileReader provide() {\n" + >+ " return reader23;\n" + // responsibility now lies at the caller of this method >+ " }\n" + >+ " };\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. WARNING in X.java (at line 4)\n" + >+ " final FileReader reader31 = new FileReader(\"file\");\n" + >+ " ^^^^^^^^\n" + >+ "Potential resource leak: 'reader31' may not be closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// resource assigned to second local and is (potentially) closed on the latter >+public void test056z() { >+ Map options = getCompilerOptions(); >+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.FileReader;\n" + >+ "public class X {\n" + >+ " void foo17() throws Exception {\n" + >+ " FileReader reader17 = new FileReader(\"file\");\n" + >+ " final FileReader readerCopy = reader17;\n" + >+ " readerCopy.close();\n" + >+ " }\n" + >+ " void foo17a() throws Exception {\n" + >+ " FileReader reader17a = new FileReader(\"file\");\n" + >+ " FileReader readerCopya;" + >+ " readerCopya = reader17a;\n" + >+ " bar(readerCopya);\n" + // potentially closes >+ " }\n" + >+ " void bar(FileReader r) {}\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 9)\n" + >+ " FileReader reader17a = new FileReader(\"file\");\n" + >+ " ^^^^^^^^^\n" + >+ "Potential resource leak: 'reader17a' may not be closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// multiple early exists from nested scopes (always closed) >+public void test056zz() { >+ Map options = getCompilerOptions(); >+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR); >+ runTestsExpectingErrorsOnlyIn17( >+ new String[] { >+ "X.java", >+ "import java.io.FileReader;\n" + >+ "public class X {\n" + >+ " void foo16() throws Exception {\n" + >+ " FileReader reader16 = new FileReader(\"file\");\n" + >+ " try {\n" + >+ " reader16.close();\n " + >+ " return;\n" + >+ " } catch (RuntimeException re) {\n" + >+ " return;\n" + >+ " } catch (Error e) {\n" + >+ " return;\n" + >+ " } finally {\n" + >+ " reader16.close();\n " + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 4)\n" + >+ " FileReader reader16 = new FileReader(\"file\");\n" + >+ " ^^^^^^^^\n" + >+ "Resource 'reader16' should be managed by try-with-resource\n" + >+ "----------\n", >+ options); >+} >+// Bug 349326 - [1.7] new warning for missing try-with-resources >+// multiple early exists from nested scopes (never closed) >+public void test056zzz() { >+ Map options = getCompilerOptions(); >+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.FileReader;\n" + >+ "public class X {\n" + >+ " void foo16() throws Exception {\n" + >+ " FileReader reader16 = new FileReader(\"file\");\n" + >+ " try {\n" + >+ " return;\n" + >+ " } catch (RuntimeException re) {\n" + >+ " return;\n" + >+ " } catch (Error e) {\n" + >+ " return;\n" + >+ " } finally {\n" + >+ " System.out.println();\n " + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 4)\n" + >+ " FileReader reader16 = new FileReader(\"file\");\n" + >+ " ^^^^^^^^\n" + >+ "Resource leak: 'reader16' is never closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 359334 - Analysis for resource leak warnings does not consider exceptions as method exit points >+// explicit throw is a true method exit here >+public void test056throw1() { >+ Map options = getCompilerOptions(); >+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.FileReader;\n" + >+ "public class X {\n" + >+ " void foo2(boolean a, boolean b, boolean c) throws Exception {\n" + >+ " FileReader reader = new FileReader(\"file\");\n" + >+ " if(a)\n" + >+ " throw new Exception(); //warning 1\n" + >+ " else if (b)\n" + >+ " reader.close();\n" + >+ " else if(c)\n" + >+ " throw new Exception(); //warning 2\n" + >+ " reader.close();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 6)\n" + >+ " throw new Exception(); //warning 1\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Resource leak: 'reader' is not closed at this location\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 10)\n" + >+ " throw new Exception(); //warning 2\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Resource leak: 'reader' is not closed at this location\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 359334 - Analysis for resource leak warnings does not consider exceptions as method exit points >+// close() within finally provides protection for throw >+public void test056throw2() { >+ Map options = getCompilerOptions(); >+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR); >+ runTestsExpectingErrorsOnlyIn17( >+ new String[] { >+ "X.java", >+ "import java.io.FileReader;\n" + >+ "public class X {\n" + >+ " void foo1() throws Exception {\n" + >+ " FileReader reader = new FileReader(\"file\"); // propose t-w-r\n" + >+ " try {\n" + >+ " reader.read();\n" + >+ " return;\n" + >+ " } catch (Exception e) {\n" + >+ " throw new Exception();\n" + >+ " } finally {\n" + >+ " reader.close();\n" + >+ " }\n" + >+ " }\n" + >+ "\n" + >+ " void foo2() throws Exception {\n" + >+ " FileReader reader = new FileReader(\"file\"); // propose t-w-r\n" + >+ " try {\n" + >+ " reader.read();\n" + >+ " throw new Exception(); // should not warn here\n" + >+ " } catch (Exception e) {\n" + >+ " throw new Exception();\n" + >+ " } finally {\n" + >+ " reader.close();\n" + >+ " }\n" + >+ " }\n" + >+ "\n" + >+ " void foo3() throws Exception {\n" + >+ " FileReader reader = new FileReader(\"file\"); // propose t-w-r\n" + >+ " try {\n" + >+ " reader.read();\n" + >+ " throw new Exception();\n" + >+ " } finally {\n" + >+ " reader.close();\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 4)\n" + >+ " FileReader reader = new FileReader(\"file\"); // propose t-w-r\n" + >+ " ^^^^^^\n" + >+ "Resource 'reader' should be managed by try-with-resource\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 16)\n" + >+ " FileReader reader = new FileReader(\"file\"); // propose t-w-r\n" + >+ " ^^^^^^\n" + >+ "Resource 'reader' should be managed by try-with-resource\n" + >+ "----------\n" + >+ "3. ERROR in X.java (at line 28)\n" + >+ " FileReader reader = new FileReader(\"file\"); // propose t-w-r\n" + >+ " ^^^^^^\n" + >+ "Resource 'reader' should be managed by try-with-resource\n" + >+ "----------\n", >+ options); >+} >+// Bug 359334 - Analysis for resource leak warnings does not consider exceptions as method exit points >+// close() nested within finally provides protection for throw >+public void test056throw3() { >+ Map options = getCompilerOptions(); >+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR); >+ runTestsExpectingErrorsOnlyIn17( >+ new String[] { >+ "X.java", >+ "import java.io.FileReader;\n" + >+ "public class X {\n" + >+ " void foo2x() throws Exception {\n" + >+ " FileReader reader = new FileReader(\"file\"); // propose t-w-r\n" + >+ " try {\n" + >+ " reader.read();\n" + >+ " throw new Exception(); // should not warn here\n" + >+ " } catch (Exception e) {\n" + >+ " throw new Exception();\n" + >+ " } finally {\n" + >+ " if (reader != null)\n" + >+ " try {\n" + >+ " reader.close();\n" + >+ " } catch (java.io.IOException io) {}\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 4)\n" + >+ " FileReader reader = new FileReader(\"file\"); // propose t-w-r\n" + >+ " ^^^^^^\n" + >+ "Resource 'reader' should be managed by try-with-resource\n" + >+ "----------\n", >+ options); >+} >+// Bug 359334 - Analysis for resource leak warnings does not consider exceptions as method exit points >+// additional boolean should shed doubt on whether we reach the close() call >+public void test056throw4() { >+ Map options = getCompilerOptions(); >+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.FileReader;\n" + >+ "public class X {\n" + >+ " void foo2x(boolean b) throws Exception {\n" + >+ " FileReader reader = new FileReader(\"file\");\n" + >+ " try {\n" + >+ " reader.read();\n" + >+ " throw new Exception(); // should warn here\n" + >+ " } catch (Exception e) {\n" + >+ " throw new Exception(); // should warn here\n" + >+ " } finally {\n" + >+ " if (reader != null && b)\n" + // this condition is too strong to protect reader >+ " try {\n" + >+ " reader.close();\n" + >+ " } catch (java.io.IOException io) {}\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 7)\n" + >+ " throw new Exception(); // should warn here\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Potential resource leak: 'reader' may not be closed at this location\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 9)\n" + >+ " throw new Exception(); // should warn here\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Potential resource leak: 'reader' may not be closed at this location\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 359334 - Analysis for resource leak warnings does not consider exceptions as method exit points >+// similar to test056throw3() but indirectly calling close(), so doubts remain. >+public void test056throw5() { >+ Map options = getCompilerOptions(); >+ options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE, CompilerOptions.ERROR); >+ options.put(JavaCore.COMPILER_PB_DEAD_CODE, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.FileReader;\n" + >+ "public class X {\n" + >+ " void foo2x() throws Exception {\n" + >+ " FileReader reader = new FileReader(\"file\");\n" + >+ " try {\n" + >+ " reader.read();\n" + >+ " throw new Exception(); // should warn 'may not' here\n" + >+ " } catch (Exception e) {\n" + >+ " throw new Exception(); // should warn 'may not' here\n" + >+ " } finally {\n" + >+ " doClose(reader);\n" + >+ " }\n" + >+ " }\n" + >+ " void doClose(FileReader r) { try { r.close(); } catch (java.io.IOException ex) {}}\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 7)\n" + >+ " throw new Exception(); // should warn \'may not\' here\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Potential resource leak: 'reader' may not be closed at this location\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 9)\n" + >+ " throw new Exception(); // should warn \'may not\' here\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Potential resource leak: 'reader' may not be closed at this location\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 358903 - Filter practically unimportant resource leak warnings >+// Bug 360908 - Avoid resource leak warning when the underlying/chained resource is closed explicitly >+// a resource wrapper is not closed but the underlying resource is >+public void test061a() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.BufferedInputStream;\n" + >+ "import java.io.FileInputStream;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " FileInputStream fileStream = new FileInputStream(file);\n" + >+ " BufferedInputStream bis = new BufferedInputStream(fileStream);\n" + >+ " BufferedInputStream doubleWrap = new BufferedInputStream(bis);\n" + >+ " System.out.println(bis.available());\n" + >+ " fileStream.close();\n" + >+ " }\n" + >+ " void inline() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " FileInputStream fileStream;\n" + >+ " BufferedInputStream bis = new BufferedInputStream(fileStream = new FileInputStream(file));\n" + >+ " System.out.println(bis.available());\n" + >+ " fileStream.close();\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " try {\n" + >+ " new X().foo();\n" + >+ " } catch (IOException ex) {" + >+ " System.out.println(\"Got IO Exception\");\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "Got IO Exception", >+ null, >+ true, >+ null, >+ options, >+ null); >+} >+// Bug 358903 - Filter practically unimportant resource leak warnings >+// a closeable without OS resource is not closed >+public void test061b() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.StringReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " StringReader string = new StringReader(\"content\");\n" + >+ " System.out.println(string.read());\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " new X().foo();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "99", // character 'c' >+ null, >+ true, >+ null, >+ options, >+ null); >+} >+// Bug 358903 - Filter practically unimportant resource leak warnings >+// a resource wrapper is not closed but the underlying closeable is resource-free >+public void test061c() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.BufferedReader;\n" + >+ "import java.io.StringReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " StringReader input = new StringReader(\"content\");\n" + >+ " BufferedReader br = new BufferedReader(input);\n" + >+ " BufferedReader doubleWrap = new BufferedReader(br);\n" + >+ " System.out.println(br.read());\n" + >+ " }\n" + >+ " void inline() throws IOException {\n" + >+ " BufferedReader br = new BufferedReader(new StringReader(\"content\"));\n" + >+ " System.out.println(br.read());\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " new X().foo();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "99", >+ null, >+ true, >+ null, >+ options, >+ null); >+} >+// Bug 358903 - Filter practically unimportant resource leak warnings >+// a resource wrapper is not closed neither is the underlying resource >+public void test061d() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.WARNING); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.BufferedInputStream;\n" + >+ "import java.io.FileInputStream;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " FileInputStream fileStream = new FileInputStream(file);\n" + >+ " BufferedInputStream bis = new BufferedInputStream(fileStream);\n" + >+ " BufferedInputStream doubleWrap = new BufferedInputStream(bis);\n" + >+ " System.out.println(bis.available());\n" + >+ " }\n" + >+ " void inline() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " BufferedInputStream bis2 = new BufferedInputStream(new FileInputStream(file));\n" + >+ " System.out.println(bis2.available());\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " try {\n" + >+ " new X().foo();\n" + >+ " } catch (IOException ex) {" + >+ " System.out.println(\"Got IO Exception\");\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 10)\n" + >+ " BufferedInputStream doubleWrap = new BufferedInputStream(bis);\n" + >+ " ^^^^^^^^^^\n" + >+ "Resource leak: \'doubleWrap\' is never closed\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 15)\n" + >+ " BufferedInputStream bis2 = new BufferedInputStream(new FileInputStream(file));\n" + >+ " ^^^^\n" + >+ "Resource leak: \'bis2\' is never closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 358903 - Filter practically unimportant resource leak warnings >+// Bug 361073 - Avoid resource leak warning when the top level resource is closed explicitly >+// a resource wrapper is closed closing also the underlying resource >+public void test061e() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.BufferedInputStream;\n" + >+ "import java.io.FileInputStream;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " FileInputStream fis;" + >+ " void foo() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " FileInputStream fileStream = new FileInputStream(file);\n" + >+ " BufferedInputStream bis = new BufferedInputStream(fileStream);\n" + >+ " BufferedInputStream doubleWrap = new BufferedInputStream(bis);\n" + >+ " System.out.println(bis.available());\n" + >+ " bis.close();\n" + >+ " }\n" + >+ " void inline() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " BufferedInputStream bis2 = new BufferedInputStream(fis = new FileInputStream(file));\n" + // field assignment >+ " System.out.println(bis2.available());\n" + >+ " bis2.close();\n" + >+ " FileInputStream fileStream = null;\n" + >+ " BufferedInputStream bis3 = new BufferedInputStream(fileStream = new FileInputStream(file));\n" + >+ " System.out.println(bis3.available());\n" + >+ " bis3.close();\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " try {\n" + >+ " new X().foo();\n" + >+ " } catch (IOException ex) {" + >+ " System.out.println(\"Got IO Exception\");\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "Got IO Exception", >+ null, >+ true, >+ null, >+ options, >+ null); >+} >+// Bug 358903 - Filter practically unimportant resource leak warnings >+// Bug 361073 - Avoid resource leak warning when the top level resource is closed explicitly >+// a resource wrapper is closed closing also the underlying resource - original test case >+public void test061f() throws IOException { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ URL url = FileLocator.toFileURL(FileLocator.find(Platform.getBundle("org.eclipse.jdt.core.tests.compiler"), new Path("META-INF/MANIFEST.MF"), null)); >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.InputStream;\n" + >+ "import java.io.InputStreamReader;\n" + >+ "import java.io.BufferedReader;\n" + >+ "import java.io.IOException;\n" + >+ "import java.net.URL;\n" + >+ "public class X {\n" + >+ " boolean loadURL(final URL url) throws IOException {\n" + >+ " InputStream stream = null;\n" + >+ " BufferedReader reader = null;\n" + >+ " try {\n" + >+ " stream = url.openStream();\n" + >+ " reader = new BufferedReader(new InputStreamReader(stream));\n" + >+ " System.out.println(reader.readLine());\n" + >+ " } finally {\n" + >+ " try {\n" + >+ " if (reader != null)\n" + >+ " reader.close();\n" + >+ " } catch (IOException x) {\n" + >+ " }\n" + >+ " }\n" + >+ " return false; // 'stream' may not be closed at this location\n" + >+ " }\n" + >+ " public static void main(String[] args) throws IOException {\n" + >+ " try {\n" + >+ " new X().loadURL(new URL(\""+url.toString()+"\"));\n" + >+ " } catch (IOException ex) {\n" + >+ " System.out.println(\"Got IO Exception\"+ex);\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "Manifest-Version: 1.0", >+ null, >+ true, >+ null, >+ options, >+ null); >+} >+// Bug 358903 - Filter practically unimportant resource leak warnings >+// Bug 361073 - Avoid resource leak warning when the top level resource is closed explicitly >+// a resource wrapper is closed closing also the underlying resource - from a real-world example >+public void test061f2() throws IOException { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.OutputStream;\n" + >+ "import java.io.FileOutputStream;\n" + >+ "import java.io.BufferedOutputStream;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void zork() throws IOException {\n" + >+ " try {\n" + >+ " OutputStream os = null;\n" + >+ " try {\n" + >+ " os = new BufferedOutputStream(new FileOutputStream(\"somefile\"));\n" + >+ " String externalForm = \"externalPath\";\n" + >+ " } finally {\n" + >+ " if (os != null)\n" + >+ " os.close();\n" + >+ " }\n" + >+ " } catch (IOException e) {\n" + >+ " e.printStackTrace();\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "", >+ null, >+ true, >+ null, >+ options, >+ null); >+} >+// Bug 358903 - Filter practically unimportant resource leak warnings >+// Bug 361073 - Avoid resource leak warning when the top level resource is closed explicitly >+// a resource wrapper is sent to another method affecting also the underlying resource - from a real-world example >+public void test061f3() throws IOException { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileInputStream;\n" + >+ "import java.io.FileNotFoundException;\n" + >+ "import java.io.InputStream;\n" + >+ "import java.io.BufferedInputStream;\n" + >+ "public class X {\n" + >+ " String loadProfile(File profileFile) {\n" + >+ " try {\n" + >+ " InputStream stream = new BufferedInputStream(new FileInputStream(profileFile));\n" + >+ " return loadProfile(stream);\n" + >+ " } catch (FileNotFoundException e) {\n" + >+ " //null\n" + >+ " }\n" + >+ " return null;\n" + >+ " }\n" + >+ " private String loadProfile(InputStream stream) {\n" + >+ " return null;\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 10)\n" + >+ " return loadProfile(stream);\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Potential resource leak: \'stream\' may not be closed at this location\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 358903 - Filter practically unimportant resource leak warnings >+// Bug 360908 - Avoid resource leak warning when the underlying/chained resource is closed explicitly >+// Different points in a resource chain are closed >+public void test061g() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.BufferedInputStream;\n" + >+ "import java.io.FileInputStream;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void closeMiddle() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " FileInputStream fileStream = new FileInputStream(file);\n" + >+ " BufferedInputStream bis = new BufferedInputStream(fileStream);\n" + >+ " BufferedInputStream doubleWrap = new BufferedInputStream(bis);\n" + >+ " System.out.println(bis.available());\n" + >+ " bis.close();\n" + >+ " }\n" + >+ " void closeOuter() throws IOException {\n" + >+ " File file2 = new File(\"somefile\");\n" + >+ " FileInputStream fileStream2 = new FileInputStream(file2);\n" + >+ " BufferedInputStream bis2 = new BufferedInputStream(fileStream2);\n" + >+ " BufferedInputStream doubleWrap2 = new BufferedInputStream(bis2);\n" + >+ " System.out.println(bis2.available());\n" + >+ " doubleWrap2.close();\n" + >+ " }\n" + >+ " void neverClosed() throws IOException {\n" + >+ " File file3 = new File(\"somefile\");\n" + >+ " FileInputStream fileStream3 = new FileInputStream(file3);\n" + >+ " BufferedInputStream bis3 = new BufferedInputStream(fileStream3);\n" + >+ " BufferedInputStream doubleWrap3 = new BufferedInputStream(bis3);\n" + >+ " System.out.println(doubleWrap3.available());\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 26)\n" + >+ " BufferedInputStream doubleWrap3 = new BufferedInputStream(bis3);\n" + >+ " ^^^^^^^^^^^\n" + >+ "Resource leak: \'doubleWrap3\' is never closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 358903 - Filter practically unimportant resource leak warnings >+// Bug 360908 - Avoid resource leak warning when the underlying/chained resource is closed explicitly >+// Different points in a resource chain are potentially closed >+public void test061h() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.BufferedInputStream;\n" + >+ "import java.io.FileInputStream;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void closeMiddle(boolean b) throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " FileInputStream fileStream = new FileInputStream(file);\n" + >+ " BufferedInputStream bis = new BufferedInputStream(fileStream);\n" + >+ " BufferedInputStream doubleWrap = new BufferedInputStream(bis);\n" + >+ " System.out.println(bis.available());\n" + >+ " if (b)\n" + >+ " bis.close();\n" + >+ " }\n" + >+ " void closeOuter(boolean b) throws IOException {\n" + >+ " File file2 = new File(\"somefile\");\n" + >+ " FileInputStream fileStream2 = new FileInputStream(file2);\n" + >+ " BufferedInputStream dummy;\n" + >+ " BufferedInputStream bis2 = (dummy = new BufferedInputStream(fileStream2));\n" + >+ " BufferedInputStream doubleWrap2 = new BufferedInputStream(bis2);\n" + >+ " System.out.println(bis2.available());\n" + >+ " if (b)\n" + >+ " doubleWrap2.close();\n" + >+ " }\n" + >+ " void potAndDef(boolean b) throws IOException {\n" + >+ " File file3 = new File(\"somefile\");\n" + >+ " FileInputStream fileStream3 = new FileInputStream(file3);\n" + >+ " BufferedInputStream bis3 = new BufferedInputStream(fileStream3);\n" + >+ " BufferedInputStream doubleWrap3 = new BufferedInputStream(bis3);\n" + >+ " System.out.println(doubleWrap3.available());\n" + >+ " if (b) bis3.close();\n" + >+ " fileStream3.close();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 10)\n" + >+ " BufferedInputStream doubleWrap = new BufferedInputStream(bis);\n" + >+ " ^^^^^^^^^^\n" + >+ "Potential resource leak: \'doubleWrap\' may not be closed\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 20)\n" + >+ " BufferedInputStream doubleWrap2 = new BufferedInputStream(bis2);\n" + >+ " ^^^^^^^^^^^\n" + >+ "Potential resource leak: \'doubleWrap2\' may not be closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 358903 - Filter practically unimportant resource leak warnings >+// local var is re-used for two levels of wrappers >+public void test061i() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.InputStream;\n" + >+ "import java.io.BufferedInputStream;\n" + >+ "import java.io.FileInputStream;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void closeMiddle() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " InputStream stream = new FileInputStream(file);\n" + >+ " stream = new BufferedInputStream(stream);\n" + >+ " InputStream middle;\n" + >+ " stream = new BufferedInputStream(middle = stream);\n" + >+ " System.out.println(stream.available());\n" + >+ " middle.close();\n" + >+ " }\n" + >+ " void closeOuter() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " InputStream stream2 = new FileInputStream(file);\n" + >+ " stream2 = new BufferedInputStream(stream2);\n" + >+ " stream2 = new BufferedInputStream(stream2);\n" + >+ " System.out.println(stream2.available());\n" + >+ " stream2.close();\n" + >+ " }\n" + >+ " void neverClosed() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " InputStream stream3 = new FileInputStream(file);\n" + >+ " stream3 = new BufferedInputStream(stream3);\n" + >+ " stream3 = new BufferedInputStream(stream3);\n" + >+ " System.out.println(stream3.available());\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 26)\n" + >+ " InputStream stream3 = new FileInputStream(file);\n" + >+ " ^^^^^^^\n" + >+ "Resource leak: \'stream3\' is never closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 358903 - Filter practically unimportant resource leak warnings >+// self-wrapping a method argument (caused NPE UnconditionalFlowInfo.markAsDefinitelyNull(..)). >+public void test061j() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.InputStream;\n" + >+ "import java.io.BufferedInputStream;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo(InputStream stream) throws IOException {\n" + >+ " stream = new BufferedInputStream(stream);\n" + >+ " System.out.println(stream.available());\n" + >+ " stream.close();\n" + >+ " }\n" + >+ " void boo(InputStream stream2) throws IOException {\n" + >+ " stream2 = new BufferedInputStream(stream2);\n" + >+ " System.out.println(stream2.available());\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "", >+ null, >+ true, >+ null, >+ options, >+ null); >+} >+// Bug 358903 - Filter practically unimportant resource leak warnings >+// a wrapper is created in a return statement >+public void test061k() throws IOException { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileInputStream;\n" + >+ "import java.io.BufferedInputStream;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " BufferedInputStream getReader(File file) throws IOException {\n" + >+ " FileInputStream stream = new FileInputStream(file);\n" + >+ " return new BufferedInputStream(stream);\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "", >+ null, >+ true, >+ null, >+ options, >+ null); >+} >+// Bug 358903 - Filter practically unimportant resource leak warnings >+// a closeable is assigned to a field >+public void test061l() throws IOException { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileInputStream;\n" + >+ "import java.io.BufferedInputStream;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " BufferedInputStream stream;\n" + >+ " void foo(File file) throws IOException {\n" + >+ " FileInputStream s = new FileInputStream(file);\n" + >+ " stream = new BufferedInputStream(s);\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "", >+ null, >+ true, >+ null, >+ options, >+ null); >+} >+// Bug 361407 - Resource leak warning when resource is assigned to a field outside of constructor >+// a closeable is assigned to a field - constructor vs. method >+public void test061l2() throws IOException { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "xy/Leaks.java", >+ "package xy;\n" + >+ "\n" + >+ "import java.io.FileInputStream;\n" + >+ "import java.io.IOException;\n" + >+ "\n" + >+ "public class Leaks {\n" + >+ " private FileInputStream fInput;\n" + >+ "\n" + >+ " Leaks(String name) throws IOException {\n" + >+ " FileInputStream fileInputStream= new FileInputStream(name);\n" + >+ " fInput= fileInputStream;\n" + // warning silenced by field assignment >+ " Objects.hashCode(fInput);\n" + >+ " \n" + >+ " init(name);\n" + >+ " }\n" + >+ " \n" + >+ " Leaks() throws IOException {\n" + >+ " this(new FileInputStream(\"default\")); // potential problem\n" + >+ " }\n" + >+ " \n" + >+ " Leaks(FileInputStream fis) throws IOException {\n" + >+ " fInput= fis;\n" + >+ " }\n" + >+ " void init(String name) throws IOException {\n" + >+ " FileInputStream fileInputStream= new FileInputStream(name);\n" + >+ " fInput= fileInputStream;\n" + // warning silenced by field assignment >+ " Objects.hashCode(fInput);\n" + >+ " }\n" + >+ " \n" + >+ " public void dispose() throws IOException {\n" + >+ " fInput.close();\n" + >+ " }\n" + >+ "}\n" + >+ "class Objects {\n" + // mock java.util.Objects (@since 1.7). >+ " static int hashCode(Object o) { return 13; }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in xy\\Leaks.java (at line 18)\n" + >+ " this(new FileInputStream(\"default\")); // potential problem\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Potential resource leak: \'<unassigned Closeable value>\' may not be closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 361407 - Resource leak warning when resource is assigned to a field outside of constructor >+// a closeable is not assigned to a field - constructor vs. method >+public void test061l3() throws IOException { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "xy/Leaks.java", >+ "package xy;\n" + >+ "\n" + >+ "import java.io.FileInputStream;\n" + >+ "import java.io.IOException;\n" + >+ "\n" + >+ "public class Leaks {\n" + >+ "\n" + >+ " Leaks(String name) throws IOException {\n" + >+ " FileInputStream fileInputStream= new FileInputStream(name);\n" + >+ " Objects.hashCode(fileInputStream);\n" + >+ " \n" + >+ " init(name);\n" + >+ " }\n" + >+ " void init(String name) throws IOException {\n" + >+ " FileInputStream fileInputStream= new FileInputStream(name);\n" + >+ " Objects.hashCode(fileInputStream);\n" + >+ " }\n" + >+ "}\n" + >+ "class Objects {\n" + // mock java.util.Objects (@since 1.7). >+ " static int hashCode(Object o) { return 13; }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in xy\\Leaks.java (at line 9)\n" + >+ " FileInputStream fileInputStream= new FileInputStream(name);\n" + >+ " ^^^^^^^^^^^^^^^\n" + >+ "Potential resource leak: \'fileInputStream\' may not be closed\n" + >+ "----------\n" + >+ "2. ERROR in xy\\Leaks.java (at line 15)\n" + >+ " FileInputStream fileInputStream= new FileInputStream(name);\n" + >+ " ^^^^^^^^^^^^^^^\n" + >+ "Potential resource leak: \'fileInputStream\' may not be closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 358903 - Filter practically unimportant resource leak warnings >+// a closeable is passed to another method in a return statement >+// example constructed after org.eclipse.equinox.internal.p2.artifact.repository.simple.SimpleArtifactRepository#getArtifact(..) >+public void test061m() throws IOException { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileInputStream;\n" + >+ "import java.io.BufferedInputStream;\n" + >+ "import java.io.InputStream;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " BufferedInputStream stream;\n" + >+ " BufferedInputStream foo(File file) throws IOException {\n" + >+ " FileInputStream s = new FileInputStream(file);\n" + >+ " return check(new BufferedInputStream(s));\n" + >+ " }\n" + >+ " BufferedInputStream foo2(FileInputStream s, File file) throws IOException {\n" + >+ " s = new FileInputStream(file);\n" + >+ " return check(s);\n" + >+ " }\n" + >+ " BufferedInputStream foo3(InputStream s) throws IOException {\n" + >+ " s = check(s);\n" + >+ " return check(s);\n" + >+ " }\n" + >+ " BufferedInputStream check(InputStream s) { return null; }\n" + >+ "}\n" >+ }, >+ // TODO: also these warnings *might* be avoidable by detecting check(s) as a wrapper creation?? >+ "----------\n" + >+ "1. ERROR in X.java (at line 10)\n" + >+ " return check(new BufferedInputStream(s));\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Potential resource leak: \'<unassigned Closeable value>\' may not be closed at this location\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 14)\n" + >+ " return check(s);\n" + >+ " ^^^^^^^^^^^^^^^^\n" + >+ "Potential resource leak: \'s\' may not be closed at this location\n" + >+ "----------\n" + >+ "3. ERROR in X.java (at line 18)\n" + >+ " return check(s);\n" + >+ " ^^^^^^^^^^^^^^^^\n" + >+ "Potential resource leak: \'s\' may not be closed at this location\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 358903 - Filter practically unimportant resource leak warnings >+// a resource wrapper does not wrap any provided resource >+public void test061n() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.PrintWriter;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " PrintWriter writer = new PrintWriter(\"filename\");\n" + >+ " writer.write(1);\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 5)\n" + >+ " PrintWriter writer = new PrintWriter(\"filename\");\n" + >+ " ^^^^^^\n" + >+ "Resource leak: \'writer\' is never closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 358903 - Filter practically unimportant resource leak warnings >+// a resource wrapper is closed only in its local block, underlying resource may leak >+public void test061o() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileInputStream;\n" + >+ "import java.io.BufferedInputStream;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo(boolean bar) throws IOException {\n" + >+ " File file = new File(\"somefil\");\n" + >+ " FileInputStream fileStream = new FileInputStream(file);\n" + >+ " BufferedInputStream bis = new BufferedInputStream(fileStream); \n" + >+ " if (bar) {\n" + >+ " BufferedInputStream doubleWrap = new BufferedInputStream(bis);\n" + >+ " doubleWrap.close();\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 9)\n" + >+ " BufferedInputStream bis = new BufferedInputStream(fileStream); \n" + >+ " ^^^\n" + >+ "Potential resource leak: \'bis\' may not be closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 358903 - Filter practically unimportant resource leak warnings >+// a resource wrapper is conditionally allocated but not closed - from a real-world example >+public void test061f4() throws IOException { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileInputStream;\n" + >+ "import java.io.FileNotFoundException;\n" + >+ "import java.io.InputStream;\n" + >+ "import java.io.BufferedInputStream;\n" + >+ "public class X {\n" + >+ " void foo(File location, String adviceFilePath) throws FileNotFoundException {\n" + >+ " InputStream stream = null;\n" + >+ " if (location.isDirectory()) {\n" + >+ " File adviceFile = new File(location, adviceFilePath);\n" + >+ " stream = new BufferedInputStream(new FileInputStream(adviceFile));\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 11)\n" + >+ " stream = new BufferedInputStream(new FileInputStream(adviceFile));\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Potential resource leak: \'stream\' may not be closed\n" + // message could be stronger, but the enclosing if blurs the picture >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 358903 - Filter practically unimportant resource leak warnings >+// a t-w-r wraps an existing resource >+public void test061p() { >+ if (this.complianceLevel < ClassFileConstants.JDK1_7) return; >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.PrintWriter;\n" + >+ "import java.io.BufferedWriter;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " PrintWriter writer = new PrintWriter(\"filename\");\n" + >+ " try (BufferedWriter bw = new BufferedWriter(writer)) {\n" + >+ " bw.write(1);\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "", >+ null, >+ true, >+ null, >+ options, >+ null); >+} >+// Bug 358903 - Filter practically unimportant resource leak warnings >+// a t-w-r potentially wraps an existing resource >+// DISABLED, fails because we currently don't include t-w-r managed resources in the analysis >+public void _test061q() { >+ if (this.complianceLevel < ClassFileConstants.JDK1_7) return; >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.PrintWriter;\n" + >+ "import java.io.BufferedWriter;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo(boolean b) throws IOException {\n" + >+ " PrintWriter writer = new PrintWriter(\"filename\");\n" + >+ " if (b)\n" + >+ " try (BufferedWriter bw = new BufferedWriter(writer)) {\n" + >+ " bw.write(1);\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 6)\n" + >+ " PrintWriter writer = new PrintWriter(\\\"filename\\\");\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Potential resource leak: \'writer\' may not be closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 358903 - Filter practically unimportant resource leak warnings >+// the inner from a wrapper is returned >+public void test061r() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.FileInputStream;\n" + >+ "import java.io.File;\n" + >+ "import java.io.BufferedInputStream;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " FileInputStream foo() throws IOException {\n" + >+ " File file = new File(\"somefil\");\n" + >+ " FileInputStream fileStream = new FileInputStream(file);\n" + >+ " BufferedInputStream bis = new BufferedInputStream(fileStream); \n" + >+ " return fileStream;\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "", >+ null, >+ true, >+ null, >+ options, >+ null); >+} >+// Bug 358903 - Filter practically unimportant resource leak warnings >+// a wrapper is forgotten, the inner is closed afterwards >+public void test061s() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.FileInputStream;\n" + >+ "import java.io.File;\n" + >+ "import java.io.BufferedInputStream;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " File file = new File(\"somefil\");\n" + >+ " FileInputStream fileStream = new FileInputStream(file);\n" + >+ " BufferedInputStream bis = new BufferedInputStream(fileStream);\n" + >+ " bis = null;\n" + >+ " fileStream.close();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "", >+ null, >+ true, >+ null, >+ options, >+ null); >+} >+// Bug 362331 - Resource leak not detected when closeable not assigned to variable >+// a resource is never assigned >+public void test062a() throws IOException { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileOutputStream;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " new FileOutputStream(new File(\"C:\\temp\\foo.txt\")).write(1);\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 6)\n" + >+ " new FileOutputStream(new File(\"C:\\temp\\foo.txt\")).write(1);\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Resource leak: \'<unassigned Closeable value>\' is never closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 362331 - Resource leak not detected when closeable not assigned to variable >+// a freshly allocated resource is immediately closed >+public void test062b() throws IOException { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileOutputStream;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " new FileOutputStream(new File(\"C:\\temp\\foo.txt\")).close();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "", >+ null, >+ true, >+ null, >+ options, >+ null); >+} >+// Bug 362331 - Resource leak not detected when closeable not assigned to variable >+// a resource is directly passed to another method >+public void test062c() throws IOException { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileOutputStream;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " writeIt(new FileOutputStream(new File(\"C:\\temp\\foo.txt\")));\n" + >+ " }\n" + >+ " void writeIt(FileOutputStream fos) throws IOException {\n" + >+ " fos.write(1);\n" + >+ " fos.close();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 6)\n" + >+ " writeIt(new FileOutputStream(new File(\"C:\\temp\\foo.txt\")));\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Potential resource leak: \'<unassigned Closeable value>\' may not be closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 362331 - Resource leak not detected when closeable not assigned to variable >+// a resource is not used >+public void test062d() throws IOException { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileOutputStream;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " new FileOutputStream(new File(\"C:\\temp\\foo.txt\"));\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 6)\n" + >+ " new FileOutputStream(new File(\"C:\\temp\\foo.txt\"));\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Resource leak: \'<unassigned Closeable value>\' is never closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 362332 - Only report potential leak when closeable not created in the local scope >+// a wrapper is obtained from another method >+public void test063a() throws IOException { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileInputStream;\n" + >+ "import java.io.BufferedInputStream;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void read(File file) throws IOException {\n" + >+ " FileInputStream stream = new FileInputStream(file);\n" + >+ " BufferedInputStream bis = new BufferedInputStream(stream); // never since reassigned\n" + >+ " FileInputStream stream2 = new FileInputStream(file); // unsure since passed to method\n" + >+ " bis = getReader(stream2); // unsure since obtained from method\n" + >+ " bis.available();\n" + >+ " }\n" + >+ " BufferedInputStream getReader(FileInputStream stream) throws IOException {\n" + >+ " return new BufferedInputStream(stream);\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 7)\n" + >+ " FileInputStream stream = new FileInputStream(file);\n" + >+ " ^^^^^^\n" + >+ "Resource leak: \'stream\' is never closed\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 9)\n" + >+ " FileInputStream stream2 = new FileInputStream(file); // unsure since passed to method\n" + >+ " ^^^^^^^\n" + >+ "Potential resource leak: \'stream2\' may not be closed\n" + >+ "----------\n" + >+ "3. ERROR in X.java (at line 10)\n" + >+ " bis = getReader(stream2); // unsure since obtained from method\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Potential resource leak: \'bis\' may not be closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 362332 - Only report potential leak when closeable not created in the local scope >+// a wrapper is obtained from a field read >+public void test063b() throws IOException { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.FileInputStream;\n" + >+ "import java.io.BufferedInputStream;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " FileInputStream stream;\n" + >+ " void read() throws IOException {\n" + >+ " FileInputStream s = this.stream;\n" + >+ " BufferedInputStream bis = new BufferedInputStream(s); // don't complain since s is obtained from a field\n" + >+ " bis.available();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "", >+ null, >+ true, >+ null, >+ options, >+ null); >+} >+// Bug 362332 - Only report potential leak when closeable not created in the local scope >+// a wrapper is assigned to a field >+public void test063c() throws IOException { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.FileInputStream;\n" + >+ "import java.io.BufferedInputStream;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " BufferedInputStream stream;\n" + >+ " void read() throws IOException {\n" + >+ " FileInputStream s = new FileInputStream(\"somefile\");\n" + >+ " BufferedInputStream bis = new BufferedInputStream(s);\n" + >+ " this.stream = bis;\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "", >+ null, >+ true, >+ null, >+ options, >+ null); >+} >+// Bug 362332 - Only report potential leak when closeable not created in the local scope >+// a resource is obtained as a method argument and/or assigned with a cast >+public void test063d() throws IOException { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR); >+ runTestsExpectingErrorsOnlyIn17( >+ new String[] { >+ "X.java", >+ "import java.io.FileInputStream;\n" + >+ "import java.io.BufferedInputStream;\n" + >+ "import java.io.InputStream;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo( InputStream input) throws IOException {\n" + >+ " FileInputStream input1 = (FileInputStream)input;\n" + >+ " System.out.println(input1.read());\n" + >+ " input.close();\n" + // don't propose t-w-r for argument >+ " }\n" + >+ " void foo() throws IOException {\n" + >+ " InputStream input = new FileInputStream(\"somefile\");\n" + >+ " FileInputStream input1 = (FileInputStream)input;\n" + >+ " System.out.println(input1.read());\n" + >+ " input.close();\n" + // do propose t-w-r, not from a method argument >+ " }\n" + >+ " void foo3( InputStream input, InputStream input2) throws IOException {\n" + >+ " FileInputStream input1 = (FileInputStream)input;\n" + // still don't claim because obtained from outside >+ " System.out.println(input1.read());\n" + >+ " BufferedInputStream bis = new BufferedInputStream(input2);\n" + >+ " System.out.println(bis.read());\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 12)\n" + >+ " InputStream input = new FileInputStream(\"somefile\");\n" + >+ " ^^^^^\n" + >+ "Resource \'input\' should be managed by try-with-resource\n" + >+ "----------\n", >+ options); >+} >+// Bug 362332 - Only report potential leak when closeable not created in the local scope >+// a resource is obtained from a field read, then re-assigned >+public void test063e() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.FileInputStream;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " FileInputStream input1;\n" + >+ " public void foo() throws IOException {\n" + >+ " FileInputStream input = input1;\n" + >+ " input = new FileInputStream(\"adfafd\");\n" + >+ " input.close();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "", >+ null, >+ true, >+ null, >+ options, >+ null); >+} >+// Bug 368709 - Endless loop in FakedTrackingVariable.markPassedToOutside >+// original test case from jgit >+public void testBug368709a() { >+ if (this.complianceLevel < ClassFileConstants.JDK1_5) return; >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.*;\n" + >+ "import java.util.zip.*;\n" + >+ "public class X {\n" + >+ " Object db, pack;\n" + // mock >+ " int objectOffset, headerLength, type, size;\n" + >+ " public ObjectStream openStream() throws MissingObjectException, IOException {\n" + >+ " WindowCursor wc = new WindowCursor(db);\n" + >+ " InputStream in;\n" + >+ " try\n" + >+ " {\n" + >+ " in = new PackInputStream(pack, (objectOffset + headerLength), wc);\n" + >+ " }\n" + >+ " catch (IOException packGone)\n" + >+ " {\n" + >+ " return wc.open(getObjectId(), type).openStream();\n" + >+ " }\n" + >+ " in = new BufferedInputStream(new InflaterInputStream(in, wc.inflater(), 8192), 8192);\n" + >+ " return new ObjectStream.Filter(type, size, in);\n" + >+ " }\n" + >+ " String getObjectId() { return \"\"; }\n" + // mock >+ "}\n" + >+ // mock: >+ "class WindowCursor {\n" + >+ " WindowCursor(Object db) {}\n" + >+ " ObjectStream open(String id, int type) { return null; }\n" + >+ " Inflater inflater() { return null; }\n" + >+ "}\n" + >+ "class MissingObjectException extends Exception {\n" + >+ " public static final long serialVersionUID = 13L;\n" + >+ " MissingObjectException() { super();}\n" + >+ "}\n" + >+ "class PackInputStream extends InputStream {\n" + >+ " PackInputStream(Object pack, int offset, WindowCursor wc) throws IOException {}\n" + >+ " public int read() { return 0; }\n" + >+ "}\n" + >+ "class ObjectStream extends InputStream {\n" + >+ " static class Filter extends ObjectStream {\n" + >+ " Filter(int type, int size, InputStream in) { }\n" + >+ " }\n" + >+ " ObjectStream openStream() { return this; }\n" + >+ " public int read() { return 0; }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 18)\n" + >+ " return new ObjectStream.Filter(type, size, in);\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Potential resource leak: \'in\' may not be closed at this location\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 368709 - Endless loop in FakedTrackingVariable.markPassedToOutside >+// minimal test case: constructing an indirect self-wrapper >+public void testBug368709b() { >+ if (this.complianceLevel < ClassFileConstants.JDK1_5) return; >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.*;\n" + >+ "import java.util.zip.*;\n" + >+ "public class X {\n" + >+ " void doit() throws IOException {\n" + >+ " InputStream in = new FileInputStream(\"somefile\");\n" + >+ " in = new BufferedInputStream(new InflaterInputStream(in, inflater(), 8192), 8192);\n" + >+ " process(in);\n" + >+ " }\n" + >+ " Inflater inflater() { return null; }\n" + >+ " void process(InputStream is) { }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 5)\n" + >+ " InputStream in = new FileInputStream(\"somefile\");\n" + >+ " ^^\n" + >+ "Potential resource leak: \'in\' may not be closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+ >+// Bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK >+// example from comment 3 >+public void test064() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ this.runNegativeTest(new String[] { >+ "Test064.java", >+ "import java.io.*;\n" + >+ "public class Test064 {\n" + >+ " void foo(File outfile) {\n" + >+ " OutputStream out= System.out;\n" + >+ " if (outfile != null) {\n" + >+ " try {\n" + >+ " out = new FileOutputStream(outfile);\n" + >+ " } catch (java.io.IOException e) {\n" + >+ " throw new RuntimeException(e);\n" + >+ " }\n" + >+ " }\n" + >+ " setOutput(out);\n" + >+ " }\n" + >+ " private void setOutput(OutputStream out) { }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in Test064.java (at line 7)\n" + >+ " out = new FileOutputStream(outfile);\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Potential resource leak: \'out\' may not be closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK >+// example from comment 10 >+// disabled, because basic null-analysis machinery doesn't support this pattern >+// see also Bug 370424 - [compiler][null] throw-catch analysis for null flow could be more precise >+public void _test065() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportMissingSerialVersion, CompilerOptions.IGNORE); >+ this.runConformTest(new String[] { >+ "Test065.java", >+ "import java.io.*;\n" + >+ "class MyException extends Exception{}\n" + >+ "public class Test065 {\n" + >+ " void foo(String fileName) throws IOException, MyException {\n" + >+ " FileReader fileRead = new FileReader(fileName);\n" + >+ " BufferedReader bufRead = new BufferedReader(fileRead);\n" + >+ " LineNumberReader lineReader = new LineNumberReader(bufRead);\n" + >+ " try {\n" + >+ " while (lineReader.readLine() != null) {\n" + >+ " bufRead.close();\n" + >+ " callSome(); // only this can throw MyException\n" + >+ " }\n" + >+ " } catch (MyException e) {\n" + >+ " throw e; // Pot. leak reported here\n" + >+ " }\n" + >+ " bufRead.close(); \n" + >+ " }\n" + >+ " private void callSome() throws MyException\n" + >+ " {\n" + >+ " \n" + >+ " }\n" + >+ "}\n" >+ }, >+ "", >+ null, >+ true, >+ null, >+ options, >+ null); >+} >+ >+// Bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK >+// example from comment 11 >+public void test066() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportMissingSerialVersion, CompilerOptions.IGNORE); >+ this.runNegativeTest(new String[] { >+ "Test066.java", >+ "import java.io.*;\n" + >+ "class MyException extends Exception{}\n" + >+ "public class Test066 {\n" + >+ " void countFileLines(String fileName) throws IOException {\n" + >+ " FileReader fileRead = new FileReader(fileName);\n" + >+ " BufferedReader bufRead = new BufferedReader(fileRead);\n" + >+ " LineNumberReader lineReader = new LineNumberReader(bufRead);\n" + >+ " while (lineReader.readLine() != null) {\n" + >+ " if (lineReader.markSupported())\n" + >+ " throw new IOException();\n" + >+ " bufRead.close();\n" + >+ " }\n" + >+ " bufRead.close();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in Test066.java (at line 10)\n" + >+ " throw new IOException();\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Potential resource leak: \'lineReader\' may not be closed at this location\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK >+// example from comment 11 - variant with closing top-level resource >+public void test066b() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportMissingSerialVersion, CompilerOptions.IGNORE); >+ this.runNegativeTest(new String[] { >+ "Test066.java", >+ "import java.io.*;\n" + >+ "class MyException extends Exception{}\n" + >+ "public class Test066 {\n" + >+ " void countFileLines(String fileName) throws IOException {\n" + >+ " FileReader fileRead = new FileReader(fileName);\n" + >+ " BufferedReader bufRead = new BufferedReader(fileRead);\n" + >+ " LineNumberReader lineReader = new LineNumberReader(bufRead);\n" + >+ " while (lineReader.readLine() != null) {\n" + >+ " if (lineReader.markSupported())\n" + >+ " throw new IOException();\n" + >+ " lineReader.close();\n" + >+ " }\n" + >+ " lineReader.close();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in Test066.java (at line 10)\n" + >+ " throw new IOException();\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Potential resource leak: \'lineReader\' may not be closed at this location\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+ >+// Bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK >+// example from comment 12 >+// disabled because null info after try-catch is too weak, >+// see also Bug 370424 - [compiler][null] throw-catch analysis for null flow could be more precise >+public void _test067() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportMissingSerialVersion, CompilerOptions.IGNORE); >+ this.runConformTest(new String[] { >+ "Test067.java", >+ "import java.io.*;\n" + >+ "public class Test067 {\n" + >+ " public void comment12() throws IOException {\n" + >+ " LineNumberReader o = null;\n" + >+ " try {\n" + >+ " o = new LineNumberReader(null); \n" + >+ " } catch (NumberFormatException e) { \n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "", >+ null, >+ true, >+ null, >+ options, >+ null); >+} >+ >+// Bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK >+// example from comment 12 >+// disabled because null info after try-catch is too weak, >+// see also Bug 370424 - [compiler][null] throw-catch analysis for null flow could be more precise >+public void _test067b() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportMissingSerialVersion, CompilerOptions.IGNORE); >+ this.runConformTest(new String[] { >+ "Test067.java", >+ "import java.io.*;\n" + >+ "public class Test067 {\n" + >+ " public void comment12b() throws IOException {\n" + >+ " LineNumberReader o = new LineNumberReader(null);\n" + >+ " try {\n" + >+ " o.close();\n" + >+ " } catch (NumberFormatException e) {\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "", >+ null, >+ true, >+ null, >+ options, >+ null); >+} >+ >+// Bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK >+// example from comment 13 >+public void test068() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportMissingSerialVersion, CompilerOptions.IGNORE); >+ this.runConformTest(new String[] { >+ "Test068.java", >+ "import java.io.*;\n" + >+ "public class Test068 {\n" + >+ " class ProcessingStep extends OutputStream {\n" + >+ " public void write(int b) throws IOException {}\n" + >+ " public OutputStream getDestination() { return null; }\n" + >+ " }\n" + >+ " class ArtifactOutputStream extends OutputStream {\n" + >+ " public void write(int b) throws IOException {}\n" + >+ " }" + >+ " ArtifactOutputStream comment13(OutputStream stream) {\n" + >+ " OutputStream current = stream;\n" + >+ " while (current instanceof ProcessingStep)\n" + >+ " current = ((ProcessingStep) current).getDestination();\n" + // we previously saw a bogus warning here. >+ " if (current instanceof ArtifactOutputStream)\n" + >+ " return (ArtifactOutputStream) current;\n" + >+ " return null;\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "", >+ null, >+ true, >+ null, >+ options, >+ null); >+} >+ >+// Bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK >+// example from comment 16 >+public void test069() { >+ if (this.complianceLevel < ClassFileConstants.JDK1_5) return; // generics used >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportMissingSerialVersion, CompilerOptions.IGNORE); >+ this.runConformTest(new String[] { >+ "Test069.java", >+ "import java.io.*;\n" + >+ "import java.util.Collection;\n" + >+ "public class Test069 {\n" + >+ " class Profile {}\n" + >+ " class CoreException extends Exception {}\n" + >+ " void writeProfilesToStream(Collection<Profile> p, OutputStream s, String enc) {}\n" + >+ " CoreException createException(IOException ioex, String message) { return new CoreException(); }\n" + >+ " public void comment16(Collection<Profile> profiles, File file, String encoding) throws CoreException {\n" + >+ " final OutputStream stream;\n" + >+ " try {\n" + >+ " stream= new FileOutputStream(file);\n" + >+ " try {\n" + >+ " writeProfilesToStream(profiles, stream, encoding);\n" + >+ " } finally {\n" + >+ " try { stream.close(); } catch (IOException e) { /* ignore */ }\n" + >+ " }\n" + >+ " } catch (IOException e) {\n" + >+ " throw createException(e, \"message\"); // should not shout here\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "", >+ null, >+ true, >+ null, >+ options, >+ null); >+} >+ >+// Bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK >+// referenced in array initializer >+public void test070() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportMissingSerialVersion, CompilerOptions.IGNORE); >+ this.runNegativeTest(new String[] { >+ "Test070.java", >+ "import java.io.*;\n" + >+ "public class Test070 {\n" + >+ " void storeInArray(String fileName) throws IOException {\n" + >+ " FileReader fileRead = new FileReader(fileName);\n" + >+ " closeThemAll(new FileReader[] { fileRead });\n" + >+ " }\n" + >+ " void closeThemAll(FileReader[] readers) { }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in Test070.java (at line 4)\n" + >+ " FileReader fileRead = new FileReader(fileName);\n" + >+ " ^^^^^^^^\n" + >+ "Potential resource leak: \'fileRead\' may not be closed\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+ >+// Bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK >+// referenced in array initializer >+public void test071() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportMissingSerialVersion, CompilerOptions.IGNORE); >+ this.runNegativeTest(new String[] { >+ "Test071.java", >+ "import java.io.*;\n" + >+ "public class Test071 {\n" + >+ " class ReaderHolder {\n" + >+ " FileReader reader;\n" + >+ " }\n" + >+ " private FileReader getReader() {\n" + >+ " return null;\n" + >+ " }\n" + >+ " void invokeCompiler(ReaderHolder readerHolder, boolean flag) throws FileNotFoundException {\n" + >+ " FileReader reader = readerHolder.reader;\n" + >+ " if (reader == null)\n" + >+ " reader = getReader();\n" + >+ " try {\n" + >+ " return;\n" + >+ " } finally {\n" + >+ " try {\n" + >+ " if (flag)\n" + >+ " reader.close();\n" + >+ " } catch (IOException e) {\n" + >+ " // nop\n" + >+ " }\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in Test071.java (at line 14)\n" + >+ " return;\n" + >+ " ^^^^^^^\n" + >+ "Potential resource leak: \'reader\' may not be closed at this location\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+ >+// Bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK >+// referenced in array initializer >+// disabled because it would require correlation analysis between the tracking variable and its original >+// need to pass to downstream: either (nonnull & open) or (null) >+public void _test071b() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportMissingSerialVersion, CompilerOptions.IGNORE); >+ this.runNegativeTest(new String[] { >+ "Test071b.java", >+ "import java.io.*;\n" + >+ "public class Test071b {\n" + >+ " private FileReader getReader() {\n" + >+ " return null;\n" + >+ " }\n" + >+ " void invokeCompiler(boolean flag) throws FileNotFoundException {\n" + >+ " FileReader reader = null;\n" + >+ " if (flag)\n" + >+ " reader = new FileReader(\"file\");\n" + >+ " if (reader == null)\n" + >+ " reader = getReader();\n" + >+ " try {\n" + >+ " return;\n" + >+ " } finally {\n" + >+ " try {\n" + >+ " if (flag)\n" + >+ " reader.close();\n" + >+ " } catch (IOException e) {\n" + >+ " // nop\n" + >+ " }\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in Test071b.java (at line 13)\n" + >+ " return;\n" + >+ " ^^^^^^^\n" + >+ "Potential resource leak: \'reader\' may not be closed at this location\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+ >+// Bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK >+// throw inside loop inside try - while closed in finally >+public void test072() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportMissingSerialVersion, CompilerOptions.IGNORE); >+ this.runConformTest(new String[] { >+ "Test072.java", >+ "import java.io.*;\n" + >+ "public class Test072 {\n" + >+ " void readState(File file) {\n" + >+ " DataInputStream in = null;\n" + >+ " try {\n" + >+ " in= new DataInputStream(new BufferedInputStream(new FileInputStream(file)));\n" + >+ " int sizeOfFlags = in.readInt();\n" + >+ " for (int i = 0; i < sizeOfFlags; ++i) {\n" + >+ " String childPath = in.readUTF();\n" + >+ " if (childPath.length() == 0)\n" + >+ " throw new IOException();\n" + >+ " }\n" + >+ " }\n" + >+ " catch (IOException ioe) { /* nop */ }\n" + >+ " finally {\n" + >+ " if (in != null) {\n" + >+ " try {in.close();} catch (IOException ioe) {}\n" + >+ " }\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "", >+ null, >+ true, >+ null, >+ options, >+ null); >+} >+ >+// Bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK >+// unspecific parameter is casted into a resource, yet need to mark as OWNED_BY_OUTSIDE >+public void test073() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportMissingSerialVersion, CompilerOptions.IGNORE); >+ this.runConformTest(new String[] { >+ "Test073.java", >+ "import java.io.*;\n" + >+ "public class Test073 {\n" + >+ " String getEncoding(Object reader) {\n" + >+ " if (reader instanceof FileReader) {\n" + >+ " final FileReader fr = (FileReader) reader;\n" + >+ " return fr.getEncoding();\n" + >+ " }\n" + >+ " return null;\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "", >+ null, >+ true, >+ null, >+ options, >+ null); >+} >+ >+// Bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK >+// status after nested try-finally >+public void test074() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR); >+ options.put(CompilerOptions.OPTION_ReportMissingSerialVersion, CompilerOptions.IGNORE); >+ this.runNegativeTest(new String[] { >+ "Test074.java", >+ "import java.io.*;\n" + >+ "public class Test074 {\n" + >+ " void foo() throws FileNotFoundException {\n" + >+ " FileOutputStream out = null;\n" + >+ " try {\n" + >+ " out = new FileOutputStream(\"outfile\");\n" + >+ " } finally {\n" + >+ " try {\n" + >+ " out.flush();\n" + >+ " out.close();\n" + >+ " } catch (IOException e) {\n" + >+ " e.printStackTrace();\n" + >+ " }\n" + >+ " out = null;\n" + // unclosed if exception occurred on flush() >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in Test074.java (at line 14)\n" + >+ " out = null;\n" + >+ " ^^^^^^^^^^\n" + >+ "Potential resource leak: \'out\' may not be closed at this location\n" + >+ "----------\n", >+ null, >+ true, >+ options); >+} >+// Bug 370639 - [compiler][resource] restore the default for resource leak warnings >+// check that the default is warning >+public void test075() { >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "public class X {\n" + >+ " void foo() throws IOException {\n" + >+ " File file = new File(\"somefile\");\n" + >+ " FileReader fileReader = new FileReader(file);\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. WARNING in X.java (at line 7)\n" + >+ " FileReader fileReader = new FileReader(file);\n" + >+ " ^^^^^^^^^^\n" + >+ "Resource leak: 'fileReader' is never closed\n" + >+ "----------\n"); >+} >+} >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ScannerTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ScannerTest.java >index 84f81da..6e782c5 100644 >--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ScannerTest.java >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ScannerTest.java >@@ -31,7 +31,7 @@ > // All specified tests which does not belong to the class are skipped... > static { > // TESTS_NAMES = new String[] { "test000" }; >-// TESTS_NUMBERS = new int[] { 58 }; >+// TESTS_NUMBERS = new int[] { 60 }; > // TESTS_RANGE = new int[] { 54, -1 }; > } > >@@ -1290,4 +1290,20 @@ > "----------\n"); > } > } >+ //https://bugs.eclipse.org/bugs/show_bug.cgi?id=352553 >+ public void test060() { >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " public static final String ERROR = \"\\u000Ⅻ\";\n" + >+ "}" >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 2)\n" + >+ " public static final String ERROR = \"\\u000Ⅻ\";\n" + >+ " ^^^^^^\n" + >+ "Invalid unicode\n" + >+ "----------\n"); >+ } > } >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java >index de0e7c6..8b83af7 100644 >--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2006, 2011 IBM Corporation and others. >+ * Copyright (c) 2006, 2012 IBM Corporation 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 >@@ -19,6 +19,7 @@ > import org.eclipse.jdt.core.ToolFactory; > import org.eclipse.jdt.core.tests.util.Util; > import org.eclipse.jdt.core.util.ClassFileBytesDisassembler; >+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; > > public class StackMapAttributeTest extends AbstractRegressionTest { > public StackMapAttributeTest(String name) { >@@ -33,7 +34,7 @@ > // All specified tests which does not belong to the class are skipped... > static { > // TESTS_PREFIX = "testBug95521"; >-// TESTS_NAMES = new String[] { "testBug83127a" }; >+// TESTS_NAMES = new String[] { "testBug359495" }; > // TESTS_NUMBERS = new int[] { 53 }; > // TESTS_RANGE = new int[] { 23 -1,}; > } >@@ -6802,4 +6803,817 @@ > }, > "SUCCESS"); > } >+ >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=359495 >+ public void testBug359495a() throws Exception { >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.util.List;\n" + >+ "import java.util.concurrent.locks.Lock;\n" + >+ "import java.util.Arrays;\n" + >+ "import java.util.concurrent.locks.ReentrantLock;\n" + >+ "public class X {\n" + >+ " public static void main(String[] args) {\n" + >+ " final Lock lock = new ReentrantLock();\n" + >+ " final List<String> strings = Arrays.asList(args);\n" + >+ " lock.lock();\n" + >+ " try{\n" + >+ " for (final String string:strings){\n" + >+ " return;\n" + >+ " }\n" + >+ " return;\n" + >+ " } finally {\n" + >+ " lock.unlock();\n" + >+ " }" + >+ " }\n" + >+ "}", >+ }, >+ ""); >+ >+ ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler(); >+ byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(new File(OUTPUT_DIR + File.separator +"X.class")); >+ String actualOutput = >+ disassembler.disassemble( >+ classFileBytes, >+ "\n", >+ ClassFileBytesDisassembler.DETAILED); >+ >+ String expectedOutput = >+ " // Method descriptor #15 ([Ljava/lang/String;)V\n" + >+ " // Stack: 2, Locals: 6\n" + >+ " public static void main(java.lang.String[] args);\n" + >+ " 0 new java.util.concurrent.locks.ReentrantLock [16]\n" + >+ " 3 dup\n" + >+ " 4 invokespecial java.util.concurrent.locks.ReentrantLock() [18]\n" + >+ " 7 astore_1 [lock]\n" + >+ " 8 aload_0 [args]\n" + >+ " 9 invokestatic java.util.Arrays.asList(java.lang.Object[]) : java.util.List [19]\n" + >+ " 12 astore_2 [strings]\n" + >+ " 13 aload_1 [lock]\n" + >+ " 14 invokeinterface java.util.concurrent.locks.Lock.lock() : void [25] [nargs: 1]\n" + >+ " 19 aload_2 [strings]\n" + >+ " 20 invokeinterface java.util.List.iterator() : java.util.Iterator [30] [nargs: 1]\n" + >+ " 25 astore 4\n" + >+ " 27 aload 4\n" + >+ " 29 invokeinterface java.util.Iterator.hasNext() : boolean [36] [nargs: 1]\n" + >+ " 34 ifeq 55\n" + >+ " 37 aload 4\n" + >+ " 39 invokeinterface java.util.Iterator.next() : java.lang.Object [42] [nargs: 1]\n" + >+ " 44 checkcast java.lang.String [46]\n" + >+ " 47 astore_3 [string]\n" + >+ " 48 aload_1 [lock]\n" + >+ " 49 invokeinterface java.util.concurrent.locks.Lock.unlock() : void [48] [nargs: 1]\n" + >+ " 54 return\n" + >+ " 55 aload_1 [lock]\n" + >+ " 56 invokeinterface java.util.concurrent.locks.Lock.unlock() : void [48] [nargs: 1]\n" + >+ " 61 return\n" + >+ " 62 astore 5\n" + >+ " 64 aload_1 [lock]\n" + >+ " 65 invokeinterface java.util.concurrent.locks.Lock.unlock() : void [48] [nargs: 1]\n" + >+ " 70 aload 5\n" + >+ " 72 athrow\n" + >+ " Exception Table:\n" + >+ " [pc: 19, pc: 48] -> 62 when : any\n" + >+ " Line numbers:\n" + >+ " [pc: 0, line: 7]\n" + >+ " [pc: 8, line: 8]\n" + >+ " [pc: 13, line: 9]\n" + >+ " [pc: 19, line: 11]\n" + >+ " [pc: 48, line: 16]\n" + >+ " [pc: 54, line: 12]\n" + >+ " [pc: 55, line: 16]\n" + >+ " [pc: 61, line: 14]\n" + >+ " [pc: 62, line: 15]\n" + >+ " [pc: 64, line: 16]\n" + >+ " [pc: 70, line: 17]\n" + >+ " Local variable table:\n" + >+ " [pc: 0, pc: 73] local: args index: 0 type: java.lang.String[]\n" + >+ " [pc: 8, pc: 73] local: lock index: 1 type: java.util.concurrent.locks.Lock\n" + >+ " [pc: 13, pc: 73] local: strings index: 2 type: java.util.List\n" + >+ " [pc: 48, pc: 55] local: string index: 3 type: java.lang.String\n" + >+ " Local variable type table:\n" + >+ " [pc: 13, pc: 73] local: strings index: 2 type: java.util.List<java.lang.String>\n" + >+ " Stack map table: number of frames 2\n" + >+ " [pc: 55, append: {java.util.concurrent.locks.Lock, java.util.List}]\n" + >+ " [pc: 62, same_locals_1_stack_item, stack: {java.lang.Throwable}]\n" ; >+ >+ int index = actualOutput.indexOf(expectedOutput); >+ if (index == -1 || expectedOutput.length() == 0) { >+ System.out.println(Util.displayString(actualOutput, 2)); >+ } >+ if (index == -1) { >+ assertEquals("Wrong contents", expectedOutput, actualOutput); >+ } >+ } >+ >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=359495 >+ public void testBug359495b() throws Exception { >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.util.List;\n" + >+ "import java.util.Iterator;\n" + >+ "import java.util.concurrent.locks.Lock;\n" + >+ "import java.util.Arrays;\n" + >+ "import java.util.concurrent.locks.ReentrantLock;\n" + >+ "public class X {\n" + >+ " public static void main(String[] args) {\n" + >+ " final Lock lock = new ReentrantLock();\n" + >+ " final List<String> strings = Arrays.asList(args);\n" + >+ " lock.lock();\n" + >+ " try{\n" + >+ " for (Iterator i = strings.iterator(); i.hasNext();){\n" + >+ " return;\n" + >+ " }\n" + >+ " return;\n" + >+ " } finally {\n" + >+ " lock.unlock();\n" + >+ " }" + >+ " }\n" + >+ "}", >+ }, >+ ""); >+ >+ ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler(); >+ byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(new File(OUTPUT_DIR + File.separator +"X.class")); >+ String actualOutput = >+ disassembler.disassemble( >+ classFileBytes, >+ "\n", >+ ClassFileBytesDisassembler.DETAILED); >+ >+ String expectedOutput = >+ " // Method descriptor #15 ([Ljava/lang/String;)V\n" + >+ " // Stack: 2, Locals: 5\n" + >+ " public static void main(java.lang.String[] args);\n" + >+ " 0 new java.util.concurrent.locks.ReentrantLock [16]\n" + >+ " 3 dup\n" + >+ " 4 invokespecial java.util.concurrent.locks.ReentrantLock() [18]\n" + >+ " 7 astore_1 [lock]\n" + >+ " 8 aload_0 [args]\n" + >+ " 9 invokestatic java.util.Arrays.asList(java.lang.Object[]) : java.util.List [19]\n" + >+ " 12 astore_2 [strings]\n" + >+ " 13 aload_1 [lock]\n" + >+ " 14 invokeinterface java.util.concurrent.locks.Lock.lock() : void [25] [nargs: 1]\n" + >+ " 19 aload_2 [strings]\n" + >+ " 20 invokeinterface java.util.List.iterator() : java.util.Iterator [30] [nargs: 1]\n" + >+ " 25 astore_3 [i]\n" + >+ " 26 aload_3 [i]\n" + >+ " 27 invokeinterface java.util.Iterator.hasNext() : boolean [36] [nargs: 1]\n" + >+ " 32 ifeq 42\n" + >+ " 35 aload_1 [lock]\n" + >+ " 36 invokeinterface java.util.concurrent.locks.Lock.unlock() : void [42] [nargs: 1]\n" + >+ " 41 return\n" + >+ " 42 aload_1 [lock]\n" + >+ " 43 invokeinterface java.util.concurrent.locks.Lock.unlock() : void [42] [nargs: 1]\n" + >+ " 48 return\n" + >+ " 49 astore 4\n" + >+ " 51 aload_1 [lock]\n" + >+ " 52 invokeinterface java.util.concurrent.locks.Lock.unlock() : void [42] [nargs: 1]\n" + >+ " 57 aload 4\n" + >+ " 59 athrow\n" + >+ " Exception Table:\n" + >+ " [pc: 19, pc: 35] -> 49 when : any\n" + >+ " Line numbers:\n" + >+ " [pc: 0, line: 8]\n" + >+ " [pc: 8, line: 9]\n" + >+ " [pc: 13, line: 10]\n" + >+ " [pc: 19, line: 12]\n" + >+ " [pc: 35, line: 17]\n" + >+ " [pc: 41, line: 13]\n" + >+ " [pc: 42, line: 17]\n" + >+ " [pc: 48, line: 15]\n" + >+ " [pc: 49, line: 16]\n" + >+ " [pc: 51, line: 17]\n" + >+ " [pc: 57, line: 18]\n" + >+ " Local variable table:\n" + >+ " [pc: 0, pc: 60] local: args index: 0 type: java.lang.String[]\n" + >+ " [pc: 8, pc: 60] local: lock index: 1 type: java.util.concurrent.locks.Lock\n" + >+ " [pc: 13, pc: 60] local: strings index: 2 type: java.util.List\n" + >+ " [pc: 26, pc: 42] local: i index: 3 type: java.util.Iterator\n" + >+ " Local variable type table:\n" + >+ " [pc: 13, pc: 60] local: strings index: 2 type: java.util.List<java.lang.String>\n" + >+ " Stack map table: number of frames 2\n" + >+ " [pc: 42, append: {java.util.concurrent.locks.Lock, java.util.List}]\n" + >+ " [pc: 49, same_locals_1_stack_item, stack: {java.lang.Throwable}]\n"; >+ >+ int index = actualOutput.indexOf(expectedOutput); >+ if (index == -1 || expectedOutput.length() == 0) { >+ System.out.println(Util.displayString(actualOutput, 2)); >+ } >+ if (index == -1) { >+ assertEquals("Wrong contents", expectedOutput, actualOutput); >+ } >+ } >+ >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=362591 >+ public void test055() throws Exception { >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " public static void main(String[] args) {\n" + >+ " testError(3, 4, \"d\");\n" + >+ " }\n" + >+ " public static void testError(Number n0, Number n1, String refValue) {\n" + >+ " Number result = refValue.equals(\"ttt\") ? n0 : (n1 == null ? null : n1.intValue());\n" + >+ " System.out.println(String.valueOf(result));\n" + >+ " }\n" + >+ "}", >+ }, >+ "4"); >+ >+ ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler(); >+ byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(new File(OUTPUT_DIR + File.separator +"X.class")); >+ String actualOutput = >+ disassembler.disassemble( >+ classFileBytes, >+ "\n", >+ ClassFileBytesDisassembler.DETAILED); >+ >+ String expectedOutput = >+ " // Method descriptor #27 (Ljava/lang/Number;Ljava/lang/Number;Ljava/lang/String;)V\n" + >+ " // Stack: 2, Locals: 4\n" + >+ " public static void testError(java.lang.Number n0, java.lang.Number n1, java.lang.String refValue);\n" + >+ " 0 aload_2 [refValue]\n" + >+ " 1 ldc <String \"ttt\"> [30]\n" + >+ " 3 invokevirtual java.lang.String.equals(java.lang.Object) : boolean [32]\n" + >+ " 6 ifeq 13\n" + >+ " 9 aload_0 [n0]\n" + >+ " 10 goto 28\n" + >+ " 13 aload_1 [n1]\n" + >+ " 14 ifnonnull 21\n" + >+ " 17 aconst_null\n" + >+ " 18 goto 28\n" + >+ " 21 aload_1 [n1]\n" + >+ " 22 invokevirtual java.lang.Number.intValue() : int [38]\n" + >+ " 25 invokestatic java.lang.Integer.valueOf(int) : java.lang.Integer [16]\n" + >+ " 28 astore_3 [result]\n" + >+ " 29 getstatic java.lang.System.out : java.io.PrintStream [44]\n" + >+ " 32 aload_3 [result]\n" + >+ " 33 invokestatic java.lang.String.valueOf(java.lang.Object) : java.lang.String [50]\n" + >+ " 36 invokevirtual java.io.PrintStream.println(java.lang.String) : void [53]\n" + >+ " 39 return\n" + >+ " Line numbers:\n" + >+ " [pc: 0, line: 6]\n" + >+ " [pc: 29, line: 7]\n" + >+ " [pc: 39, line: 8]\n" + >+ " Local variable table:\n" + >+ " [pc: 0, pc: 40] local: n0 index: 0 type: java.lang.Number\n" + >+ " [pc: 0, pc: 40] local: n1 index: 1 type: java.lang.Number\n" + >+ " [pc: 0, pc: 40] local: refValue index: 2 type: java.lang.String\n" + >+ " [pc: 29, pc: 40] local: result index: 3 type: java.lang.Number\n" + >+ " Stack map table: number of frames 3\n" + >+ " [pc: 13, same]\n" + >+ " [pc: 21, same]\n" + >+ " [pc: 28, same_locals_1_stack_item, stack: {java.lang.Number}]\n"; >+ >+ int index = actualOutput.indexOf(expectedOutput); >+ if (index == -1 || expectedOutput.length() == 0) { >+ System.out.println(Util.displayString(actualOutput, 2)); >+ } >+ if (index == -1) { >+ assertEquals("Wrong contents", expectedOutput, actualOutput); >+ } >+ } >+ >+ public void test055a() throws Exception { >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " public static void main(String[] args) {\n" + >+ " Object o = args != null ? args : (args == null ? null : args.length);\n" + >+ " }\n" + >+ "}\n", >+ }, >+ ""); >+ } >+ //https://bugs.eclipse.org/bugs/show_bug.cgi?id=366999 >+ public void test056() throws Exception { >+ if (this.complianceLevel < ClassFileConstants.JDK1_7) return; >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.BufferedReader;\n" + >+ "import java.io.Closeable;\n" + >+ "import java.io.File;\n" + >+ "import java.io.FileReader;\n" + >+ "import java.io.IOException;\n" + >+ "\n" + >+ "public class X {\n" + >+ "\n" + >+ " static class C implements Closeable {\n" + >+ " @Override\n" + >+ " public void close() throws IOException {\n" + >+ " //\n" + >+ " }\n" + >+ " }\n" + >+ "\n" + >+ " int run() throws IOException {\n" + >+ " int lcnt = 0;\n" + >+ " try (C c = new C();) {\n" + >+ " try (final BufferedReader br = new BufferedReader(new FileReader(\n" + >+ " new File(\"logging.properties\")))) {\n" + >+ " String s = null;\n" + >+ " while ((s = br.readLine()) != null)\n" + >+ " lcnt++;\n" + >+ " return lcnt;\n" + >+ " }\n" + >+ " } finally {\n" + >+ " System.out.println(\"read \" + lcnt + \" lines\");\n" + >+ " }\n" + >+ " }\n" + >+ "\n" + >+ " public static void main(final String[] args) throws IOException {\n" + >+ " System.out.println(\"SUCCESS\");\n" + >+ " }\n" + >+ "}", >+ }, >+ "SUCCESS"); >+ } >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023 >+ public void test057() throws Exception { >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " public void run() {\n" + >+ " String s;\n" + >+ " label1: do {\n" + >+ " for (;;) {\n" + >+ " s = \"\";\n" + >+ " if (s == null) \n" + >+ " continue label1;\n" + >+ " }\n" + >+ " } while (s != null);\n" + >+ "}\n" + >+ " public static void main(String [] args) {\n" + >+ " System.out.println(\"SUCCESS\");\n" + >+ " }\n" + >+ "}\n", >+ }, >+ "SUCCESS"); >+ } >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023 >+ public void test058() throws Exception { >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " public void run() {\n" + >+ " String s;\n" + >+ " label1: do {\n" + >+ " for (;true;) {\n" + >+ " s = \"\";\n" + >+ " if (s == null) \n" + >+ " continue label1;\n" + >+ " }\n" + >+ " } while (s != null);\n" + >+ "}\n" + >+ " public static void main(String [] args) {\n" + >+ " System.out.println(\"SUCCESS\");\n" + >+ " }\n" + >+ "}\n" }, >+ "SUCCESS"); >+ } >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023 >+ public void test059() throws Exception { >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " public void run() {\n" + >+ " String s;\n" + >+ " label1: do {\n" + >+ " for (;false;) {\n" + >+ " s = \"\";\n" + >+ " if (s == null) \n" + >+ " continue label1;\n" + >+ " }\n" + >+ " } while (s != null);\n" + >+ "}\n" + >+ " public static void main(String [] args) {\n" + >+ " System.out.println(\"SUCCESS\");\n" + >+ " }\n" + >+ "}\n" }, >+ "----------\n" + >+ "1. WARNING in X.java (at line 4)\n" + >+ " label1: do {\n" + >+ " ^^^^^^\n" + >+ "The label label1 is never explicitly referenced\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 5)\n" + >+ " for (;false;) {\n" + >+ " s = \"\";\n" + >+ " if (s == null) \n" + >+ " continue label1;\n" + >+ " }\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Unreachable code\n" + >+ "----------\n" + >+ "3. ERROR in X.java (at line 10)\n" + >+ " } while (s != null);\n" + >+ " ^\n" + >+ "The local variable s may not have been initialized\n" + >+ "----------\n"); >+ } >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023 >+ public void test060() throws Exception { >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " public void run() {\n" + >+ " String s;\n" + >+ " label1: do {\n" + >+ " for (; 5 < 10;) {\n" + >+ " s = \"\";\n" + >+ " if (s == null) \n" + >+ " continue label1;\n" + >+ " }\n" + >+ " } while (s != null);\n" + >+ "}\n" + >+ " public static void main(String [] args) {\n" + >+ " System.out.println(\"SUCCESS\");\n" + >+ " }\n" + >+ "}\n" }, >+ "SUCCESS"); >+ } >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023 >+ public void test061() throws Exception { >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " public void run() {\n" + >+ " int five = 5, ten = 10;\n" + >+ " String s;\n" + >+ " label1: do {\n" + >+ " for (; five < ten;) {\n" + >+ " s = \"\";\n" + >+ " if (s == null) \n" + >+ " continue label1;\n" + >+ " }\n" + >+ " } while (s != null);\n" + >+ "}\n" + >+ " public static void main(String [] args) {\n" + >+ " System.out.println(\"SUCCESS\");\n" + >+ " }\n" + >+ "}\n" }, >+ "----------\n" + >+ "1. WARNING in X.java (at line 9)\n" + >+ " continue label1;\n" + >+ " ^^^^^^^^^^^^^^^^\n" + >+ "Dead code\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 11)\n" + >+ " } while (s != null);\n" + >+ " ^\n" + >+ "The local variable s may not have been initialized\n" + >+ "----------\n"); >+ } >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023 >+ public void test062() throws Exception { >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " public void run() {\n" + >+ " final int five = 5, ten = 10;\n" + >+ " String s;\n" + >+ " label1: do {\n" + >+ " for (; five < ten;) {\n" + >+ " s = \"\";\n" + >+ " if (s == null) \n" + >+ " continue label1;\n" + >+ " }\n" + >+ " } while (s != null);\n" + >+ "}\n" + >+ " public static void main(String [] args) {\n" + >+ " System.out.println(\"SUCCESS\");\n" + >+ " }\n" + >+ "}\n" }, >+ "SUCCESS"); >+ } >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023 >+ public void test063() throws Exception { >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " public void run() {\n" + >+ " final int five = 5, ten = 10;\n" + >+ " String s;\n" + >+ " label1: do {\n" + >+ " for (; five > ten;) {\n" + >+ " s = \"\";\n" + >+ " if (s == null) \n" + >+ " continue label1;\n" + >+ " }\n" + >+ " } while (s != null);\n" + >+ "}\n" + >+ " public static void main(String [] args) {\n" + >+ " System.out.println(\"SUCCESS\");\n" + >+ " }\n" + >+ "}\n" }, >+ "----------\n" + >+ "1. WARNING in X.java (at line 5)\n" + >+ " label1: do {\n" + >+ " ^^^^^^\n" + >+ "The label label1 is never explicitly referenced\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 6)\n" + >+ " for (; five > ten;) {\n" + >+ " s = \"\";\n" + >+ " if (s == null) \n" + >+ " continue label1;\n" + >+ " }\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Unreachable code\n" + >+ "----------\n" + >+ "3. ERROR in X.java (at line 11)\n" + >+ " } while (s != null);\n" + >+ " ^\n" + >+ "The local variable s may not have been initialized\n" + >+ "----------\n"); >+ } >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023 >+ public void test064() throws Exception { >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " public void run() {\n" + >+ " String s;\n" + >+ " label1: do {\n" + >+ " while (true) {\n" + >+ " s = \"\";\n" + >+ " if (s == null) \n" + >+ " continue label1;\n" + >+ " }\n" + >+ " } while (s != null);\n" + >+ "}\n" + >+ " public static void main(String [] args) {\n" + >+ " System.out.println(\"SUCCESS\");\n" + >+ " }\n" + >+ "}\n", >+ }, >+ "SUCCESS"); >+ } >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023 >+ public void test065() throws Exception { >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " public void run() {\n" + >+ " String s;\n" + >+ " label1: do {\n" + >+ " while (false) {\n" + >+ " s = \"\";\n" + >+ " if (s == null) \n" + >+ " continue label1;\n" + >+ " }\n" + >+ " } while (s != null);\n" + >+ "}\n" + >+ " public static void main(String [] args) {\n" + >+ " System.out.println(\"SUCCESS\");\n" + >+ " }\n" + >+ "}\n" }, >+ "----------\n" + >+ "1. WARNING in X.java (at line 4)\n" + >+ " label1: do {\n" + >+ " ^^^^^^\n" + >+ "The label label1 is never explicitly referenced\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 5)\n" + >+ " while (false) {\n" + >+ " s = \"\";\n" + >+ " if (s == null) \n" + >+ " continue label1;\n" + >+ " }\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Unreachable code\n" + >+ "----------\n" + >+ "3. ERROR in X.java (at line 10)\n" + >+ " } while (s != null);\n" + >+ " ^\n" + >+ "The local variable s may not have been initialized\n" + >+ "----------\n"); >+ } >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023 >+ public void test066() throws Exception { >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " public void run() {\n" + >+ " String s;\n" + >+ " label1: do {\n" + >+ " while(5 < 10) {\n" + >+ " s = \"\";\n" + >+ " if (s == null) \n" + >+ " continue label1;\n" + >+ " }\n" + >+ " } while (s != null);\n" + >+ "}\n" + >+ " public static void main(String [] args) {\n" + >+ " System.out.println(\"SUCCESS\");\n" + >+ " }\n" + >+ "}\n" }, >+ "SUCCESS"); >+ } >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023 >+ public void test067() throws Exception { >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " public void run() {\n" + >+ " int five = 5, ten = 10;\n" + >+ " String s;\n" + >+ " label1: do {\n" + >+ " while (five < ten) {\n" + >+ " s = \"\";\n" + >+ " if (s == null) \n" + >+ " continue label1;\n" + >+ " }\n" + >+ " } while (s != null);\n" + >+ "}\n" + >+ " public static void main(String [] args) {\n" + >+ " System.out.println(\"SUCCESS\");\n" + >+ " }\n" + >+ "}\n" }, >+ "----------\n" + >+ "1. WARNING in X.java (at line 9)\n" + >+ " continue label1;\n" + >+ " ^^^^^^^^^^^^^^^^\n" + >+ "Dead code\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 11)\n" + >+ " } while (s != null);\n" + >+ " ^\n" + >+ "The local variable s may not have been initialized\n" + >+ "----------\n"); >+ } >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023 >+ public void test068() throws Exception { >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " public void run() {\n" + >+ " final int five = 5, ten = 10;\n" + >+ " String s;\n" + >+ " label1: do {\n" + >+ " while (five < ten) {\n" + >+ " s = \"\";\n" + >+ " if (s == null) \n" + >+ " continue label1;\n" + >+ " }\n" + >+ " } while (s != null);\n" + >+ "}\n" + >+ " public static void main(String [] args) {\n" + >+ " System.out.println(\"SUCCESS\");\n" + >+ " }\n" + >+ "}\n" }, >+ "SUCCESS"); >+ } >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023 >+ public void test069() throws Exception { >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " public void run() {\n" + >+ " final int five = 5, ten = 10;\n" + >+ " String s;\n" + >+ " label1: do {\n" + >+ " while (five > ten) {\n" + >+ " s = \"\";\n" + >+ " if (s == null) \n" + >+ " continue label1;\n" + >+ " }\n" + >+ " } while (s != null);\n" + >+ "}\n" + >+ " public static void main(String [] args) {\n" + >+ " System.out.println(\"SUCCESS\");\n" + >+ " }\n" + >+ "}\n" }, >+ "----------\n" + >+ "1. WARNING in X.java (at line 5)\n" + >+ " label1: do {\n" + >+ " ^^^^^^\n" + >+ "The label label1 is never explicitly referenced\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 6)\n" + >+ " while (five > ten) {\n" + >+ " s = \"\";\n" + >+ " if (s == null) \n" + >+ " continue label1;\n" + >+ " }\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Unreachable code\n" + >+ "----------\n" + >+ "3. ERROR in X.java (at line 11)\n" + >+ " } while (s != null);\n" + >+ " ^\n" + >+ "The local variable s may not have been initialized\n" + >+ "----------\n"); >+ } >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023 >+ public void test070() throws Exception { >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.util.ArrayList;\n" + >+ "import java.util.Arrays;\n" + >+ "import java.util.Iterator;\n" + >+ "import java.util.List;\n" + >+ "import java.util.Properties;\n" + >+ "import org.w3c.dom.*;\n" + >+ "public class X extends Object {\n" + >+ " public static void main(String [] args) {\n" + >+ " System.out.println (\"SUCCESS\");\n" + >+ " }\n" + >+ " private static class Handler extends Object {\n" + >+ " public int getStuff() {\n" + >+ " return 1;\n" + >+ " }\n" + >+ " public void handle(Element element) {\n" + >+ " Properties properties = new Properties();\n" + >+ " NamedNodeMap atts = element.getAttributes();\n" + >+ " if (atts != null) {\n" + >+ " for (int a = 0; a < atts.getLength(); a++) {\n" + >+ " Node att = atts.item(a);\n" + >+ " String name = att.getNodeName();\n" + >+ " String value = att.getNodeValue();\n" + >+ " if (\"foo\".equals(name)) {\n" + >+ " name = value;\n" + >+ " } else {\n" + >+ " if (!\"bar\".equals(name))\n" + >+ " continue;\n" + >+ " name = value;\n" + >+ " }\n" + >+ " properties.put(name, value);\n" + >+ " }\n" + >+ " }\n" + >+ " label0: do {\n" + >+ " Node node;\n" + >+ " String nodeName;\n" + >+ " label1: do {\n" + >+ " for (Iterator i = (new ArrayList(1)).iterator(); i\n" + >+ " .hasNext(); members.add(equals(node))) {\n" + >+ " node = (Node) i.next();\n" + >+ " nodeName = \"\" + equals(node.getNodeName());\n" + >+ " if (!\"foo\".equals(nodeName))\n" + >+ " continue label1;\n" + >+ " }\n" + >+ " break label0;\n" + >+ " } while (!\"bar\".equals(nodeName));\n" + >+ " Iterator i = (new ArrayList(1)).iterator();\n" + >+ " while (i.hasNext()) {\n" + >+ " Node n = (Node) i.next();\n" + >+ " String name = toString() + n.getNodeName();\n" + >+ " if (\"wtf\".equals(name)) {\n" + >+ " String propertyName = (toString() + n.getAttributes()\n" + >+ " .getNamedItem(\"broken\")).trim();\n" + >+ " String value = toString() + n;\n" + >+ " properties.put(propertyName, value);\n" + >+ " }\n" + >+ " }\n" + >+ " } while (true);\n" + >+ " propertiesBuilder.equals(properties);\n" + >+ " builder.equals(propertiesBuilder.hashCode());\n" + >+ " builder.equals(members);\n" + >+ " }\n" + >+ " private final Object c;\n" + >+ " private Object builder;\n" + >+ " private List members;\n" + >+ " private Object propertiesBuilder;\n" + >+ " public Handler(Object c) {\n" + >+ " this.c = c;\n" + >+ " builder = Arrays.asList(Object.class);\n" + >+ " builder.equals(\"foo\");\n" + >+ " builder.equals(\"bar\");\n" + >+ " members = new ArrayList();\n" + >+ " propertiesBuilder = Arrays.asList(Object.class);\n" + >+ " Object beanDefinition = propertiesBuilder.toString();\n" + >+ " Object holder = new String(\"stirng\");\n" + >+ " Arrays.asList(holder, c.toString());\n" + >+ " }\n" + >+ " }\n" + >+ " public X() {\n" + >+ " }\n" + >+ " protected Object parseInternal(Element element, Object c) {\n" + >+ " Handler h = new Handler(c);\n" + >+ " h.handle(element);\n" + >+ " return h.getStuff();\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "SUCCESS"); >+ } > } >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StaticImportTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StaticImportTest.java >index bae6a3c..a814439 100644 >--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StaticImportTest.java >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StaticImportTest.java >@@ -2484,10 +2484,10 @@ > "}\n", > }, > "----------\n" + >- "1. ERROR in p1\\A.java (at line 7)\n" + >- " int v2 = b.fooC;\n" + >+ "1. ERROR in p1\\A.java (at line 6)\n" + >+ " int v1 = b.fooB;\n" + > " ^^^^\n" + >- "fooC cannot be resolved or is not a field\n" + >+ "fooB cannot be resolved or is not a field\n" + > "----------\n"); > } > //https://bugs.eclipse.org/bugs/show_bug.cgi?id=256375 >@@ -2720,5 +2720,362 @@ > "----------\n" > ); > } >+ >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=318401 >+ public void test081() { >+ this.runConformTest( >+ new String[] { >+ "Test.java", >+ "import static p1.Bar.B;\n" + >+ "import p3.Foo.*;\n" + >+ "public class Test {\n" + >+ " public static void main(String [] args){\n" + >+ " new Test().beginTest();" + >+ " }\n" + >+ " public void beginTest(){\n" + >+ " System.out.print(\"1 + 1 = \");\n" + >+ " if(alwaysTrue()) System.out.println(\"2\");\n" + >+ " else System.out.println(\"3\"); " + >+ " }\n" + >+ " public boolean alwaysTrue(){\n" + >+ " String myB = B.class.getCanonicalName();;\n" + // refers to p1.Bar.B (class) >+ " String realB = p1.Bar.B.class.getCanonicalName();;\n" + // refers to p1.Bar.B (class) >+ " B();\n" + // refers to p1.Bar.B() (method) >+ " return myB.equals(realB);\n" + >+ " }\n" + >+ "}\n", >+ "p1/Bar.java", >+ "package p1;\n" + >+ "public class Bar{\n" + >+ " public static class B{}\n" + >+ " final public static String B = new String(\"random\");\n" + >+ " public static void B(){}\n" + >+ "}\n", >+ "p3/Foo.java", >+ "package p3;\n" + >+ "public class Foo {\n" + >+ " public class B{\n" + >+ " public int a;\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "1 + 1 = 2"); >+ } >+ >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=318401 >+ public void test082() { >+ this.runNegativeTest( >+ new String[] { >+ "p1/Bar.java", >+ "package p1;\n" + >+ "public class Bar{\n" + >+ " public static class B{}\n" + >+ " final public static String B = new String(\"random\");\n" + >+ " public static void B(){}\n" + >+ "}\n", >+ "p3/Foo.java", >+ "package p3;\n" + >+ "public class Foo {\n" + >+ " public class B{\n" + >+ " public int a;\n" + >+ " }\n" + >+ "}\n", >+ "p2/Test.java", >+ "package p2;\n" + >+ "import static p1.Bar.B;\n" + >+ "import p3.Foo.*;\n" + >+ "public class Test {\n" + >+ " public static void main(String [] args){\n" + >+ " new Test().beginTest();" + >+ " }\n" + >+ " public void beginTest(){\n" + >+ " System.out.print(\"1 + 1 = \");\n" + >+ " if(alwaysTrue()) System.out.println(\"2\");\n" + >+ " else System.out.println(\"3\"); " + >+ " }\n" + >+ " public boolean alwaysTrue(){\n" + >+ " B b = null;\n" + // refers to p1.Bar.B (class) >+ " String realB = B;\n" + // refers to p1.Bar.B (field) >+ " B();\n" + // refers to p1.Bar.B() (method) >+ " int abc = b.a;\n;" + // static import for Bar.B overshadows on demand import Foo.B >+ " }\n" + >+ "}\n", >+ }, >+ "----------\n" + >+ "1. ERROR in p2\\Test.java (at line 15)\n" + >+ " int abc = b.a;\n" + >+ " ^\n" + >+ "a cannot be resolved or is not a field\n" + >+ "----------\n"); >+ } >+ >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=318401 >+ public void test083() { >+ this.runConformTest( >+ new String[] { >+ "Test.java", >+ "import static p1.Bar.B;\n" + >+ "import p3.Foo.*;\n" + >+ "public class Test {\n" + >+ " public static void main(String [] args){\n" + >+ " new Test().test2();" + >+ " }\n" + >+ " public void test2(){\n" + >+ " System.out.println(B.toString());\n" + // Field obscures class B >+ " System.out.println(p1.Bar.B.toString());\n" + // Field obscures the class B >+ " System.out.println(B.class.getCanonicalName().toString());\n" + // the class B >+ " System.out.println(p1.Bar.B.class.getCanonicalName().toString());" + // class B >+ " }\n" + >+ "}\n", >+ "p1/Bar.java", >+ "package p1;\n" + >+ "public class Bar{\n" + >+ " public static class B{}\n" + >+ " final public static String B = new String(\"random\");\n" + >+ " public static void B(){}\n" + >+ "}\n", >+ "p3/Foo.java", >+ "package p3;\n" + >+ "public class Foo {\n" + >+ " public class B{\n" + >+ " public int a;\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "random\n" + >+ "random\n" + >+ "p1.Bar.B\n" + >+ "p1.Bar.B"); >+ } >+ >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=318401 >+ // Check if we're able to find the correct static member type being imported, >+ // even though the import originally resolved to the static field of the same name, >+ // coming from the supertype >+ public void test084() { >+ this.runConformTest( >+ new String[] { >+ "Test.java", >+ "import static p1.Bar.B;\n" + >+ "import p3.Foo.*;\n" + >+ "public class Test {\n" + >+ " public static void main(String [] args){\n" + >+ " new Test().test2();" + >+ " }\n" + >+ " public void test2(){\n" + >+ " System.out.println(B.class.getCanonicalName().toString());\n" + // the class B >+ " System.out.println(p1.Bar.B.class.getCanonicalName().toString());" + // class B >+ " }\n" + >+ "}\n", >+ "p1/Bar.java", >+ "package p1;\n" + >+ "public class Bar extends SuperBar{\n" + >+ " public static class B{}\n" + >+ " public static void B(){}\n" + >+ "}\n", >+ "p1/SuperBar.java", >+ "package p1;\n" + >+ "public class SuperBar {\n" + >+ " final public static String B = new String(\"random\");\n" + >+ "}\n", >+ "p3/Foo.java", >+ "package p3;\n" + >+ "public class Foo {\n" + >+ " public class B{\n" + >+ " public int a;\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "p1.Bar.B\n" + >+ "p1.Bar.B"); >+ } >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=361327 >+ // To verify that all static members are imported with a single static import statement >+ public void test085() { >+ this.runNegativeTest( >+ new String[] { >+ "Test.java", >+ "import static p1.Bar.B;\n" + >+ "import static p3.Foo.B;\n" + >+ "public class Test {\n" + >+ " public static void main(String [] args){\n" + >+ " new Test().test2();" + >+ " }\n" + >+ " public void test2(){\n" + >+ " System.out.println(B.class.getCanonicalName().toString());\n" + >+ " System.out.println(p1.Bar.B.class.getCanonicalName().toString());" + >+ " }\n" + >+ "}\n", >+ "p1/Bar.java", >+ "package p1;\n" + >+ "public class Bar{\n" + >+ " public static class B{}\n" + >+ " public static String B = new String(\"random\");\n" + >+ "}\n", >+ "p3/Foo.java", >+ "package p3;\n" + >+ "public class Foo {\n" + >+ " public static class B{\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in Test.java (at line 2)\n" + >+ " import static p3.Foo.B;\n" + >+ " ^^^^^^^^\n" + >+ "The import p3.Foo.B collides with another import statement\n" + >+ "----------\n"); >+ } >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=361327 >+ // To verify that all static members are imported with a single static import statement, >+ // even from a supertype >+ public void test085a() { >+ this.runNegativeTest( >+ new String[] { >+ "Test.java", >+ "import static p1.Bar.B;\n" + >+ "import static p3.Foo.B;\n" + >+ "public class Test {\n" + >+ " public static void main(String [] args){\n" + >+ " new Test().test2();" + >+ " }\n" + >+ " public void test2(){\n" + >+ " System.out.println(B.class.getCanonicalName().toString());\n" + >+ " System.out.println(p1.Bar.B.class.getCanonicalName().toString());" + >+ " }\n" + >+ "}\n", >+ "p1/Bar.java", >+ "package p1;\n" + >+ "public class Bar extends SuperBar{\n" + >+ " public static void B(){}\n" + >+ "}\n", >+ "p1/SuperBar.java", >+ "package p1;\n" + >+ "public class SuperBar {\n" + >+ " public static class B{}\n" + >+ " final public static String B = new String(\"random\");\n" + >+ "}\n", >+ "p3/Foo.java", >+ "package p3;\n" + >+ "public class Foo {\n" + >+ " public static class B{\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in Test.java (at line 2)\n" + >+ " import static p3.Foo.B;\n" + >+ " ^^^^^^^^\n" + >+ "The import p3.Foo.B collides with another import statement\n" + >+ "----------\n"); >+ } >+ >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=361327 >+ // To verify that all static members are imported with a single static import statement >+ // this tests checks collision with single type import >+ public void test085b() { >+ this.runNegativeTest( >+ new String[] { >+ "Test.java", >+ "import static p1.Bar.B;\n" + >+ "import p3.Foo.B;\n" + >+ "public class Test {\n" + >+ " public static void main(String [] args){\n" + >+ " new Test().test2();" + >+ " }\n" + >+ " public void test2(){\n" + >+ " System.out.println(B.class.getCanonicalName().toString());\n" + >+ " System.out.println(p1.Bar.B.class.getCanonicalName().toString());" + >+ " }\n" + >+ "}\n", >+ "p1/Bar.java", >+ "package p1;\n" + >+ "public class Bar{\n" + >+ " public static class B{}\n" + >+ " public static String B = new String(\"random\");\n" + >+ "}\n", >+ "p3/Foo.java", >+ "package p3;\n" + >+ "public class Foo {\n" + >+ " public class B{\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in Test.java (at line 2)\n" + >+ " import p3.Foo.B;\n" + >+ " ^^^^^^^^\n" + >+ "The import p3.Foo.B collides with another import statement\n" + >+ "----------\n"); >+ } >+ >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=361327 >+ // To verify that all static members are imported with a single static import statement >+ // this tests checks collision with top level type >+ public void test085c() { >+ this.runNegativeTest( >+ new String[] { >+ "Test.java", >+ "import static p1.Bar.B;\n" + >+ "public class Test {\n" + >+ " public static void main(String [] args){\n" + >+ " new Test().test2();" + >+ " }\n" + >+ " public void test2(){\n" + >+ " System.out.println(B.class.getCanonicalName().toString());\n" + >+ " System.out.println(p1.Bar.B.class.getCanonicalName().toString());" + >+ " }\n" + >+ "}\n" + >+ "class B{\n" + >+ "}\n", >+ "p1/Bar.java", >+ "package p1;\n" + >+ "public class Bar{\n" + >+ " public static class B{}\n" + >+ " public static String B = new String(\"random\");\n" + >+ "}\n", >+ }, >+ "----------\n" + >+ "1. ERROR in Test.java (at line 1)\n" + >+ " import static p1.Bar.B;\n" + >+ " ^^^^^^^^\n" + >+ "The import p1.Bar.B conflicts with a type defined in the same file\n" + >+ "----------\n"); >+ } >+ >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=361327 >+ // Test obscuring rules defined in JLS 7.5.3 >+ public void test086() { >+ this.runConformTest( >+ new String[] { >+ "Test.java", >+ "import static p1.Bar.B;\n" + >+ "import static p3.Foo.*;\n" + >+ "public class Test {\n" + >+ " public static void main(String [] args){\n" + >+ " new Test().test2();" + >+ " }\n" + >+ " public void test2(){\n" + >+ " B();\n" + // should be p1.Bar.B() and not p3.Foo.B() >+ " System.out.println(B.toString());\n" + // should be p1.Bar.B >+ " }\n" + >+ "}\n", >+ "p1/Bar.java", >+ "package p1;\n" + >+ "public class Bar{\n" + >+ " public static void B(){ System.out.println(\"Bar's method B\");}\n" + >+ " public static String B = new String(\"Bar's field B\");\n" + >+ "}\n", >+ "p3/Foo.java", >+ "package p3;\n" + >+ "public class Foo {\n" + >+ " public static void B(){ System.out.println(\"Foo's method B\");}\n" + >+ " public static String B = new String(\"Foo's field B\");\n" + >+ "}\n" >+ }, >+ "Bar\'s method B\n" + >+ "Bar\'s field B"); >+ } >+ > } > >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java >index 28a772e..5f2f3d8 100644 >--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,6 +7,9 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contributions for >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 358903 - Filter practically unimportant resource leak warnings > *******************************************************************************/ > package org.eclipse.jdt.core.tests.compiler.regression; > >@@ -73,6 +76,7 @@ > standardTests.add(ProgrammingProblemsTest.class); > standardTests.add(ManifestAnalyzerTest.class); > standardTests.add(InitializationTests.class); >+ standardTests.add(ResourceLeakTests.class); > > // add all javadoc tests > for (int i=0, l=JavadocTest.ALL_CLASSES.size(); i<l; i++) { >@@ -96,6 +100,7 @@ > since_1_5.add(InnerEmulationTest_1_5.class); > since_1_5.add(AssignmentTest_1_5.class); > since_1_5.add(InnerClass15Test.class); >+ since_1_5.add(NullAnnotationTest.class); > > // Tests to run when compliance is greater than 1.5 > ArrayList since_1_6 = new ArrayList(); >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryStatementTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryStatementTest.java >index 78b5aa4..49dced1 100644 >--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryStatementTest.java >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryStatementTest.java >@@ -758,7 +758,7 @@ > "1. ERROR in X.java (at line 6)\n" + > " } catch(AX e) {\n" + > " ^^\n" + >- "Unreachable catch block for AX. Only more specific exceptions are thrown and handled by previous catch block(s).\n" + >+ "Unreachable catch block for AX. Only more specific exceptions are thrown and they are handled by previous catch block(s).\n" + > "----------\n" + > "2. WARNING in X.java (at line 10)\n" + > " class AX extends Exception {}\n" + >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryWithResourcesStatementTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryWithResourcesStatementTest.java >index e178b04..48b9ad3 100644 >--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryWithResourcesStatementTest.java >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TryWithResourcesStatementTest.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2011 IBM Corporation and others. >+ * Copyright (c) 2011, 2012 IBM Corporation 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 >@@ -7,18 +7,22 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contributions for >+ * bug 358827 - [1.7] exception analysis for t-w-r spoils null analysis >+ * bug 349326 - [1.7] new warning for missing try-with-resources >+ * bug 359334 - Analysis for resource leak warnings does not consider exceptions as method exit points > *******************************************************************************/ > package org.eclipse.jdt.core.tests.compiler.regression; > > import java.util.Map; > >-import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; >- > import junit.framework.Test; >+ >+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; > public class TryWithResourcesStatementTest extends AbstractRegressionTest { > > static { >-// TESTS_NAMES = new String[] { "test055", "test055a" }; >+// TESTS_NAMES = new String[] { "test061m"}; > // TESTS_NUMBERS = new int[] { 50 }; > // TESTS_RANGE = new int[] { 11, -1 }; > } >@@ -448,6 +452,8 @@ > } > // Test for unhandled exceptions > public void test014() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.WARNING); > this.runNegativeTest( > new String[] { > "X.java", >@@ -485,16 +491,22 @@ > " ^^\n" + > "Dead code\n" + > "----------\n" + >- "3. ERROR in X.java (at line 5)\n" + >+ "3. WARNING in X.java (at line 5)\n" + >+ " Y why = new Y();\n" + >+ " ^^^\n" + >+ "Resource leak: 'why' is never closed\n" + >+ "----------\n" + >+ "4. ERROR in X.java (at line 5)\n" + > " Y why = new Y();\n" + > " ^^^^^^^\n" + > "Unhandled exception type WeirdException\n" + > "----------\n" + >- "4. WARNING in X.java (at line 22)\n" + >+ "5. WARNING in X.java (at line 22)\n" + > " class WeirdException extends Throwable {}\n" + > " ^^^^^^^^^^^^^^\n" + > "The serializable class WeirdException does not declare a static final serialVersionUID field of type long\n" + >- "----------\n"); >+ "----------\n", >+ null, true, options); > } > // Resource nullness tests > public void test015() { >@@ -523,6 +535,8 @@ > } > // Dead code tests, resource nullness, unhandled exception tests > public void test016() { >+ Map options = getCompilerOptions(); >+ options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.WARNING); > this.runNegativeTest( > new String[] { > "X.java", >@@ -558,16 +572,24 @@ > " ^^\n" + > "Dead code\n" + > "----------\n" + >- "3. ERROR in X.java (at line 5)\n" + >+ "3. WARNING in X.java (at line 5)\n" + >+ " Y why = new Y();\n" + >+ " ^^^\n" + >+ "Resource leak: 'why' is never closed\n" + >+ "----------\n" + >+ "4. ERROR in X.java (at line 5)\n" + > " Y why = new Y();\n" + > " ^^^^^^^\n" + > "Unhandled exception type WeirdException\n" + > "----------\n" + >- "4. WARNING in X.java (at line 20)\n" + >+ "5. WARNING in X.java (at line 20)\n" + > " class WeirdException extends Throwable {}\n" + > " ^^^^^^^^^^^^^^\n" + > "The serializable class WeirdException does not declare a static final serialVersionUID field of type long\n" + >- "----------\n"); >+ "----------\n", >+ null, >+ true, >+ options); > } > // Dead code tests > public void test017() { >@@ -3297,6 +3319,57 @@ > "Unhandled exception type IOException\n" + > "----------\n"); > } >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=348705 >+// Variant of the above, witness for https://bugs.eclipse.org/358827#c6 >+public void test053a() { >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " public void method1(){\n" + >+ " try (Y y = new Y()) { \n" + >+ " y.close();\n" + >+ " System.out.println();\n" + >+ " } catch (RuntimeException e) {\n" + >+ " } finally {\n" + >+ " System.out.println();\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" + >+ "class Y implements Managed {\n" + >+ " public Y() throws CloneNotSupportedException {}\n" + >+ " public void close () throws ClassNotFoundException, java.io.IOException {\n" + >+ " }\n" + >+ "}\n" + >+ "interface Managed extends AutoCloseable {}\n", >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 3)\n" + >+ " try (Y y = new Y()) { \n" + >+ " ^\n" + >+ "Unhandled exception type ClassNotFoundException thrown by automatic close() invocation on y\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 3)\n" + >+ " try (Y y = new Y()) { \n" + >+ " ^\n" + >+ "Unhandled exception type IOException thrown by automatic close() invocation on y\n" + >+ "----------\n" + >+ "3. ERROR in X.java (at line 3)\n" + >+ " try (Y y = new Y()) { \n" + >+ " ^^^^^^^\n" + >+ "Unhandled exception type CloneNotSupportedException\n" + >+ "----------\n" + >+ "4. ERROR in X.java (at line 4)\n" + >+ " y.close();\n" + >+ " ^^^^^^^^^\n" + >+ "Unhandled exception type ClassNotFoundException\n" + >+ "----------\n" + >+ "5. ERROR in X.java (at line 4)\n" + >+ " y.close();\n" + >+ " ^^^^^^^^^\n" + >+ "Unhandled exception type IOException\n" + >+ "----------\n"); >+} > // https://bugs.eclipse.org/bugs/show_bug.cgi?id=349862 (NPE when union type is used in the resource section.) > public void test054() { > this.runNegativeTest( >@@ -3380,6 +3453,179 @@ > }, > "Done"); > } >+ >+// Note: test056* have been moved to ResourceLeakTests.java >+ >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=361053 >+public void test057() { >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "public class X implements AutoCloseable {\n" + >+ " @Override\n" + >+ " public void close() throws Exception {\n" + >+ " throw new Exception();\n" + >+ " }\n" + >+ " public static void main(String[] args) {\n" + >+ " final boolean foo;\n" + >+ " try (X a = new X(); X b = new X()) {\n" + >+ " foo = true;\n" + >+ " } catch (final Exception exception) {\n" + >+ " return;\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, ""); >+} >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=364008 >+public void test058() { >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.ByteArrayOutputStream;\n" + >+ "import java.io.FileOutputStream;\n" + >+ "import java.io.IOException;\n" + >+ "\n" + >+ "public class X {\n" + >+ "\n" + >+ " public static void main(final String[] args) throws IOException {\n" + >+ " byte[] data;\n" + >+ " try (final ByteArrayOutputStream os = new ByteArrayOutputStream();\n" + >+ " final FileOutputStream out = new FileOutputStream(\"test.dat\")) {\n" + >+ " data = os.toByteArray();\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, ""); >+} >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=367566 - In try-with-resources statement close() method of resource is not called >+public void test059() { >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "import java.io.IOException;\n" + >+ "\n" + >+ "public class X implements java.lang.AutoCloseable {\n" + >+ " static boolean isOpen = true;\n" + >+ " public static void main(final String[] args) throws IOException {\n" + >+ " foo();\n" + >+ " System.out.println(isOpen);\n" + >+ " }\n" + >+ " static boolean foo() {\n" + >+ " try (final X x = new X()) {\n" + >+ " return x.num() >= 1;\n" + >+ " }\n" + >+ " }\n" + >+ " int num() { return 2; }\n" + >+ " public void close() {\n" + >+ " isOpen = false;\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "false"); >+} >+ >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=367566 - In try-with-resources statement close() method of resource is not called >+public void test060() { >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "public class X implements AutoCloseable {\n" + >+ " static int num = 10 ;\n" + >+ " public static void main(String [] args) throws Exception { \n" + >+ " System.out.println(foo(1));\n" + >+ " System.out.println(foo(2));\n" + >+ " System.out.println(foo(3));\n" + >+ " }\n" + >+ " private static boolean foo(int where) throws Exception {\n" + >+ " final boolean getOut = true;\n" + >+ " System.out.println(\"Main\");\n" + >+ " try (X x1 = new X(); X x2 = new X()) {\n" + >+ " if (where == 1) {\n" + >+ " return where == 1;\n" + >+ " }\n" + >+ " System.out.println(\"Outer Try\");\n" + >+ " while (true) {\n" + >+ " try (Y y1 = new Y(); Y y2 = new Y()) { \n" + >+ " if (where == 2) {\n" + >+ " return where == 2;\n" + >+ " } \n" + >+ " System.out.println(\"Middle Try\");\n" + >+ " try (Z z1 = new Z(); Z z2 = new Z()) {\n" + >+ " System.out.println(\"Inner Try\");\n" + >+ " if (getOut) \n" + >+ " return num >= 10;\n" + >+ " else\n" + >+ " break; \n" + >+ " }\n" + >+ " }\n" + >+ " }\n" + >+ " System.out.println(\"Out of while\");\n" + >+ " }\n" + >+ " return false;\n" + >+ " }\n" + >+ " public X() {\n" + >+ " System.out.println(\"X::X\");\n" + >+ " }\n" + >+ " @Override\n" + >+ " public void close() throws Exception {\n" + >+ " System.out.println(\"X::~X\");\n" + >+ " }\n" + >+ "}\n" + >+ "class Y implements AutoCloseable {\n" + >+ " public Y() {\n" + >+ " System.out.println(\"Y::Y\");\n" + >+ " }\n" + >+ " @Override\n" + >+ " public void close() throws Exception {\n" + >+ " System.out.println(\"Y::~Y\");\n" + >+ " }\n" + >+ "}\n" + >+ "class Z implements AutoCloseable {\n" + >+ " public Z() {\n" + >+ " System.out.println(\"Z::Z\");\n" + >+ " }\n" + >+ " @Override\n" + >+ " public void close() throws Exception {\n" + >+ " System.out.println(\"Z::~Z\");\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "Main\n" + >+ "X::X\n" + >+ "X::X\n" + >+ "X::~X\n" + >+ "X::~X\n" + >+ "true\n" + >+ "Main\n" + >+ "X::X\n" + >+ "X::X\n" + >+ "Outer Try\n" + >+ "Y::Y\n" + >+ "Y::Y\n" + >+ "Y::~Y\n" + >+ "Y::~Y\n" + >+ "X::~X\n" + >+ "X::~X\n" + >+ "true\n" + >+ "Main\n" + >+ "X::X\n" + >+ "X::X\n" + >+ "Outer Try\n" + >+ "Y::Y\n" + >+ "Y::Y\n" + >+ "Middle Try\n" + >+ "Z::Z\n" + >+ "Z::Z\n" + >+ "Inner Try\n" + >+ "Z::~Z\n" + >+ "Z::~Z\n" + >+ "Y::~Y\n" + >+ "Y::~Y\n" + >+ "X::~X\n" + >+ "X::~X\n" + >+ "true"); >+} > public static Class testClass() { > return TryWithResourcesStatementTest.class; > } >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java >index 30e7dc7..536723b 100644 >--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java >@@ -777,7 +777,7 @@ > } > > public void test015() { // check behaviour of Scope.mostSpecificMethodBinding() >- this.runConformTest( >+ this.runNegativeTest( > new String[] { > "X.java", > "public class X {\n" + >@@ -790,7 +790,12 @@ > " public static void count(int[] array, int[] ... values) { System.out.print(2); }\n" + > "}\n", > }, >- "1" >+ "----------\n" + >+ "1. ERROR in X.java (at line 3)\n" + >+ " Y.count(new int[0]);\n" + >+ " ^^^^^\n" + >+ "The method count(int[], int[]) is ambiguous for the type Y\n" + >+ "----------\n" > ); > } > >@@ -1232,7 +1237,7 @@ > } > //https://bugs.eclipse.org/bugs/show_bug.cgi?id=102631 > public void test033() { >- this.runConformTest( >+ this.runNegativeTest( > new String[] { > "X.java", > "public class X {\n" + >@@ -1246,7 +1251,17 @@ > " }\n" + > "}\n", > }, >- "112"); >+ "----------\n" + >+ "1. ERROR in X.java (at line 6)\n" + >+ " x.a(true);\n" + >+ " ^\n" + >+ "The method a(boolean, Object[]) is ambiguous for the type X\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 7)\n" + >+ " x.a(true, \"foobar\");\n" + >+ " ^\n" + >+ "The method a(boolean, Object[]) is ambiguous for the type X\n" + >+ "----------\n"); > this.runNegativeTest( > new String[] { > "X.java", >@@ -2756,4 +2771,243 @@ > "Type safety: A generic array of Class<? extends Object&Serializable&Comparable<?>> is created for a varargs parameter\n" + > "----------\n"); > } >-} >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=346042 >+ public void test069() throws Exception { >+ if (this.complianceLevel < ClassFileConstants.JDK1_5) return; >+ this.runNegativeTest( >+ new String[] { >+ "p1/B.java", >+ "package p1;\n" + >+ "class A {\n" + >+ "}\n" + >+ "public class B extends A {\n" + >+ " public void foo(A... args) {\n" + >+ " }\n" + >+ "}\n", >+ "p2/C.java", >+ "package p2;\n" + >+ "import p1.B;\n" + >+ "public class C {\n" + >+ "\n" + >+ " public static final void main(String[] args) {\n" + >+ " (new B()).foo(new B(), new B());\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in p2\\C.java (at line 6)\n" + >+ " (new B()).foo(new B(), new B());\n" + >+ " ^^^\n" + >+ "The method foo(A...) of type B is not applicable as the formal varargs element type A is not accessible here\n" + >+ "----------\n"); >+ } >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=346038 >+ public void test070() throws Exception { >+ if (this.complianceLevel < ClassFileConstants.JDK1_5) return; >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " public static void foo(int ...i) {}\n" + >+ " public static void foo(double...d) {}\n" + >+ " public static void main(String[] args) {\n" + >+ " foo(1, 2, 3);\n" + >+ " System.out.println (\"Done\");\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "Done"); >+ } >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=346038 >+ public void test070a() throws Exception { >+ if (this.complianceLevel < ClassFileConstants.JDK1_5) return; >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " public static <T> void foo(int ...i) {}\n" + >+ " public static <T> void foo(double...d) {}\n" + >+ " public static void main(String[] args) {\n" + >+ " foo(1, 2, 3);\n" + >+ " System.out.println (\"Done\");\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "Done"); >+ } >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=346038 >+ public void test070b() throws Exception { >+ if (this.complianceLevel < ClassFileConstants.JDK1_5) return; >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " public static void foo(int ...i) {}\n" + >+ " public static void foo(double d1, double...d) {}\n" + >+ " public static void main(String[] args) {\n" + >+ " foo(1, 2, 3); // foo NOT flagged ambiguous\n" + >+ " }\n" + >+ "}\n" >+ }, >+ ""); >+ } >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=346038 >+ public void test070c() { // check behaviour of Scope.mostSpecificMethodBinding() >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " public static void main(String[] s) {\n" + >+ " count(1);\n" + >+ " count(1, 1);\n" + >+ " count(1, 1, 1);\n" + >+ " }\n" + >+ " public static void count(int ... values) {}\n" + >+ " public static void count(int i, int ... values) {}\n" + >+ "}\n", >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 3)\n" + >+ " count(1);\n" + >+ " ^^^^^\n" + >+ "The method count(int[]) is ambiguous for the type X\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 4)\n" + >+ " count(1, 1);\n" + >+ " ^^^^^\n" + >+ "The method count(int[]) is ambiguous for the type X\n" + >+ "----------\n" + >+ "3. ERROR in X.java (at line 5)\n" + >+ " count(1, 1, 1);\n" + >+ " ^^^^^\n" + >+ "The method count(int[]) is ambiguous for the type X\n" + >+ "----------\n"); >+ } >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=346038 >+ public void test070d() { // check behaviour of Scope.mostSpecificMethodBinding() >+ this.runNegativeTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " void b(boolean b, Object... o) {}\n" + >+ " void b(Boolean... o) {}\n" + >+ " void c(boolean b, boolean b2, Object... o) {}\n" + >+ " void c(Boolean b, Object... o) {}\n" + >+ " public static void main(String[] args) {\n" + >+ " X x = new X();\n" + >+ " x.b(true);\n" + >+ " x.b(true, false);\n" + >+ " }\n" + >+ "}\n", >+ }, >+ "----------\n" + >+ "1. ERROR in X.java (at line 8)\r\n" + >+ " x.b(true);\r\n" + >+ " ^\n" + >+ "The method b(boolean, Object[]) is ambiguous for the type X\n" + >+ "----------\n" + >+ "2. ERROR in X.java (at line 9)\r\n" + >+ " x.b(true, false);\r\n" + >+ " ^\n" + >+ "The method b(boolean, Object[]) is ambiguous for the type X\n" + >+ "----------\n"); >+ } >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=346039 >+ public void test071() { // check behaviour of Scope.mostSpecificMethodBinding() >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "public class X implements IClass{\n" + >+ " X(IClass c, X t, IType... args) {\n" + >+ " System.out.println (\"1\");\n" + >+ " }\n" + >+ " X(IClass c, IType... args) {\n" + >+ " System.out.println (\"2\");\n" + >+ " }\n" + >+ " public static void main(String args[]) {\n" + >+ " IClass c = null;\n" + >+ " X t = null;\n" + >+ " X t2 = new X(c, t); // incorrectly flagged ambiguous\n" + >+ " }\n" + >+ "}\n" + >+ "interface IType{}\n" + >+ "interface IClass extends IType{}\n" >+ }, >+ "1"); >+ } >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=364672 >+ public void test072() { >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " private class Z {}\n" + >+ " public void foo() {\n" + >+ " Z[] zs = null;\n" + >+ " Y.bar(zs, new Z());\n" + >+ " }\n" + >+ " public static void main(String[] args) {}\n" + >+ "}", >+ "Y.java", >+ "public class Y {\n" + >+ " public native static <T> void bar(T[] t, T t1, T... t2);\n" + >+ "}" >+ }, >+ ""); >+ } >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=364672 >+ public void test073() { >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ "public class X {\n" + >+ " public static final String CONSTANT = \"\";\n" + >+ " private static class A {\n" + >+ " A(String s, String s2, String s3, A... a) {}\n" + >+ " }\n" + >+ " private static class B extends A {\n" + >+ " B(String s, String s2) {\n" + >+ " super(s, s2, CONSTANT);\n" + >+ " }\n" + >+ " }\n" + >+ " private static void foo(Object o, A ... a) {\n" + >+ " }\n" + >+ " private static B bar() {\n" + >+ " return null;\n" + >+ " }\n" + >+ " public static void main(String[] args) {\n" + >+ " Object o = null;\n" + >+ " foo(o, bar(), bar());\n" + >+ " }\n" + >+ "}" >+ }, >+ ""); >+ } >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=364672 >+ public void test074() throws Exception { >+ this.runNegativeTest( >+ new String[] { >+ "p1/B.java", >+ "package p1;\n" + >+ "class A {}\n" + >+ "public class B extends A {\n" + >+ " public B(A... args) {}\n" + >+ " public B() {}\n" + >+ "}\n", >+ "p2/C.java", >+ "package p2;\n" + >+ "import p1.B;\n" + >+ "public class C {\n" + >+ " public static final void main(String[] args) {\n" + >+ " new B(new B(), new B());\n" + >+ " }\n" + >+ "}\n" >+ }, >+ "----------\n" + >+ "1. ERROR in p2\\C.java (at line 5)\n" + >+ " new B(new B(), new B());\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "The constructor B(A...) of type B is not applicable as the formal varargs element type A is not accessible here\n" + >+ "----------\n"); >+ } >+} >\ No newline at end of file >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/XLargeTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/XLargeTest.java >index ecb7387..215c9e6 100644 >--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/XLargeTest.java >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/XLargeTest.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2005, 2011 IBM Corporation and others. >+ * Copyright (c) 2005, 2012 IBM Corporation 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 >@@ -30,6 +30,100 @@ > return buildAllCompliancesTestSuite(testClass()); > } > >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=368435 >+public void test368435() { >+ Map settings = getCompilerOptions(); >+ settings.put(CompilerOptions.OPTION_PreserveUnusedLocal, CompilerOptions.OPTIMIZE_OUT); >+ StringBuffer sourceCode = new StringBuffer( >+ "public class X {\n" + >+ " public static void main(String[] args) {\n" + >+ " System.out.println(\"SUCCESS\");\n" + >+ " }\n" + >+ " public void print() {\n" + >+ " int i = 0;\n" + >+ " if (System.currentTimeMillis() > 17000L) {\n" + >+ " System.out.println(i++);\n"); >+ >+ for (int i = 0; i < 5000; i++) { >+ sourceCode.append("\t\t System.out.println(\"xyz\");\n"); >+ } >+ sourceCode.append("}\n}\n}\n"); >+ >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ sourceCode.toString() >+ }, >+ "SUCCESS", >+ null, >+ true, >+ null, >+ settings, >+ null); >+} >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=368435 >+public void test368435b() { >+ Map settings = getCompilerOptions(); >+ settings.put(CompilerOptions.OPTION_PreserveUnusedLocal, CompilerOptions.OPTIMIZE_OUT); >+ StringBuffer sourceCode = new StringBuffer( >+ "public class X {\n" + >+ " public static void main(String[] args) {\n" + >+ " System.out.println(\"SUCCESS\");\n" + >+ " }\n" + >+ " public X() {\n" + >+ " int i = 0;\n" + >+ " if (System.currentTimeMillis() > 17000L) {\n" + >+ " System.out.println(i++);\n"); >+ >+ for (int i = 0; i < 5000; i++) { >+ sourceCode.append("\t\t System.out.println(\"xyz\");\n"); >+ } >+ sourceCode.append("}\n}\n}\n"); >+ >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ sourceCode.toString() >+ }, >+ "SUCCESS", >+ null, >+ true, >+ null, >+ settings, >+ null); >+} >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=368435 >+public void test368435c() { >+ Map settings = getCompilerOptions(); >+ settings.put(CompilerOptions.OPTION_PreserveUnusedLocal, CompilerOptions.OPTIMIZE_OUT); >+ StringBuffer sourceCode = new StringBuffer( >+ "public class X {\n" + >+ " public static void main(String[] args) {\n" + >+ " System.out.println(\"SUCCESS\");\n" + >+ " }\n" + >+ " {\n" + >+ " int i = 0;\n" + >+ " if (System.currentTimeMillis() > 17000L) {\n" + >+ " System.out.println(i++);\n"); >+ >+ for (int i = 0; i < 5000; i++) { >+ sourceCode.append("\t\t System.out.println(\"xyz\");\n"); >+ } >+ sourceCode.append("}\n}\n}\n"); >+ >+ this.runConformTest( >+ new String[] { >+ "X.java", >+ sourceCode.toString() >+ }, >+ "SUCCESS", >+ null, >+ true, >+ null, >+ settings, >+ null); >+} >+ > public void test001() { > this.runConformTest( > new String[] { >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/TestVerifier.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/TestVerifier.java >index 8c38c58..2b47ac9 100644 >--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/TestVerifier.java >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/TestVerifier.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -116,7 +116,7 @@ > } > String fileName = dir + File.separator + simpleName + ".java"; > Util.writeToFile(getVerifyTestsCode(), fileName); >- BatchCompiler.compile("\"" + fileName + "\" -d \"" + verifierDir + "\" -classpath \"" + Util.getJavaClassLibsAsString() + "\"", new PrintWriter(System.out), new PrintWriter(System.err), null/*progress*/); >+ BatchCompiler.compile("\"" + fileName + "\" -d \"" + verifierDir + "\" -warn:-resource -classpath \"" + Util.getJavaClassLibsAsString() + "\"", new PrintWriter(System.out), new PrintWriter(System.err), null/*progress*/); > } > public void execute(String className, String[] classpaths) { > this.outputBuffer = new StringBuffer(); >@@ -145,222 +145,243 @@ > */ > private String getVerifyTestsCode() { > return >- "/*******************************************************************************" + >- " * Copyright (c) 2000, 2005 IBM Corporation 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:" + >- " * IBM Corporation - initial API and implementation" + >- " *******************************************************************************/" + >- "package org.eclipse.jdt.core.tests.util;\n" + >- "\n" + >- "import java.lang.reflect.*;\n" + >- "import java.io.*;\n" + >- "import java.net.*;\n" + >- "import java.util.*;\n" + >- "\n" + >- "/******************************************************\n" + >- " * \n" + >- " * IMPORTANT NOTE: If modifying this class, copy the source to TestVerifier#getVerifyTestsCode()\n" + >- " * (see this method for details)\n" + >- " * \n" + >- " ******************************************************/\n" + >- "\n" + >- "public class VerifyTests {\n" + >- " int portNumber;\n" + >- " Socket socket;\n" + >- "\n" + >- "/**\n" + >- " * NOTE: Code copied from junit.util.TestCaseClassLoader.\n" + >- " *\n" + >- " * A custom class loader which enables the reloading\n" + >- " * of classes for each test run. The class loader\n" + >- " * can be configured with a list of package paths that\n" + >- " * should be excluded from loading. The loading\n" + >- " * of these packages is delegated to the system class\n" + >- " * loader. They will be shared across test runs.\n" + >- " * <p>\n" + >- " * The list of excluded package paths is specified in\n" + >- " * a properties file \"excluded.properties\" that is located in \n" + >- " * the same place as the TestCaseClassLoader class.\n" + >- " * <p>\n" + >- " * <b>Known limitation:</b> the VerifyClassLoader cannot load classes\n" + >- " * from jar files.\n" + >- " */\n" + >- "\n" + >- "\n" + >- "public class VerifyClassLoader extends ClassLoader {\n" + >- " /** scanned class path */\n" + >- " private String[] fPathItems;\n" + >- " \n" + >- " /** excluded paths */\n" + >- " private String[] fExcluded= {};\n" + >- "\n" + >- " /**\n" + >- " * Constructs a VerifyClassLoader. It scans the class path\n" + >- " * and the excluded package paths\n" + >- " */\n" + >- " public VerifyClassLoader() {\n" + >- " super();\n" + >- " String classPath= System.getProperty(\"java.class.path\");\n" + >- " String separator= System.getProperty(\"path.separator\");\n" + >- " \n" + >- " // first pass: count elements\n" + >- " StringTokenizer st= new StringTokenizer(classPath, separator);\n" + >- " int i= 0;\n" + >- " while (st.hasMoreTokens()) {\n" + >- " st.nextToken();\n" + >- " i++;\n" + >- " }\n" + >- " // second pass: split\n" + >- " fPathItems= new String[i];\n" + >- " st= new StringTokenizer(classPath, separator);\n" + >- " i= 0;\n" + >- " while (st.hasMoreTokens()) {\n" + >- " fPathItems[i++]= st.nextToken();\n" + >- " }\n" + >- "\n" + >- " }\n" + >- " public java.net.URL getResource(String name) {\n" + >- " return ClassLoader.getSystemResource(name);\n" + >- " }\n" + >- " public InputStream getResourceAsStream(String name) {\n" + >- " return ClassLoader.getSystemResourceAsStream(name);\n" + >- " }\n" + >- " protected boolean isExcluded(String name) {\n" + >- " // exclude the \"java\" packages.\n" + >- " // They always need to be excluded so that they are loaded by the system class loader\n" + >- " if (name.startsWith(\"java\"))\n" + >- " return true;\n" + >- " \n" + >- " // exclude the user defined package paths\n" + >- " for (int i= 0; i < fExcluded.length; i++) {\n" + >- " if (name.startsWith(fExcluded[i])) {\n" + >- " return true;\n" + >- " }\n" + >- " }\n" + >- " return false; \n" + >- " }\n" + >- " public synchronized Class loadClass(String name, boolean resolve)\n" + >- " throws ClassNotFoundException {\n" + >- " \n" + >- " Class c= findLoadedClass(name);\n" + >- " if (c != null)\n" + >- " return c;\n" + >- " //\n" + >- " // Delegate the loading of excluded classes to the\n" + >- " // standard class loader.\n" + >- " //\n" + >- " if (isExcluded(name)) {\n" + >- " try {\n" + >- " c= findSystemClass(name);\n" + >- " return c;\n" + >- " } catch (ClassNotFoundException e) {\n" + >- " // keep searching\n" + >- " }\n" + >- " }\n" + >- " File file= locate(name);\n" + >- " if (file == null)\n" + >- " throw new ClassNotFoundException();\n" + >- " byte data[]= loadClassData(file);\n" + >- " c= defineClass(name, data, 0, data.length);\n" + >- " if (resolve) \n" + >- " resolveClass(c);\n" + >- " return c;\n" + >- " }\n" + >- " private byte[] loadClassData(File f) throws ClassNotFoundException {\n" + >- " try {\n" + >- " //System.out.println(\"loading: \"+f.getPath());\n" + >- " FileInputStream stream= new FileInputStream(f);\n" + >- " \n" + >- " try {\n" + >- " byte[] b= new byte[stream.available()];\n" + >- " stream.read(b);\n" + >- " stream.close();\n" + >- " return b;\n" + >- " }\n" + >- " catch (IOException e) {\n" + >- " throw new ClassNotFoundException();\n" + >- " }\n" + >- " }\n" + >- " catch (FileNotFoundException e) {\n" + >- " throw new ClassNotFoundException();\n" + >- " }\n" + >- " }\n" + >- " /**\n" + >- " * Locate the given file.\n" + >- " * @return Returns null if file couldn\'t be found.\n" + >- " */\n" + >- " private File locate(String fileName) { \n" + >- " if (fileName != null) {\n" + >- " fileName= fileName.replace(\'.\', \'/\')+\".class\";\n" + >- " File path= null;\n" + >- " for (int i= 0; i < fPathItems.length; i++) {\n" + >- " path= new File(fPathItems[i], fileName);\n" + >- " if (path.exists())\n" + >- " return path;\n" + >- " }\n" + >- " }\n" + >- " return null;\n" + >- " }\n" + >- "}\n" + >- " \n" + >- "public void loadAndRun(String className) throws Throwable {\n" + >- " //System.out.println(\"Loading \" + className + \"...\");\n" + >- " Class testClass = new VerifyClassLoader().loadClass(className);\n" + >- " //System.out.println(\"Loaded \" + className);\n" + >- " try {\n" + >- " Method main = testClass.getMethod(\"main\", new Class[] {String[].class});\n" + >- " //System.out.println(\"Running \" + className);\n" + >- " main.invoke(null, new Object[] {new String[] {}});\n" + >- " //System.out.println(\"Finished running \" + className);\n" + >- " } catch (NoSuchMethodException e) {\n" + >- " return;\n" + >- " } catch (InvocationTargetException e) {\n" + >- " throw e.getTargetException();\n" + >- " }\n" + >- "}\n" + >- "public static void main(String[] args) throws IOException {\n" + >- " VerifyTests verify = new VerifyTests();\n" + >- " verify.portNumber = Integer.parseInt(args[0]);\n" + >- " verify.run();\n" + >- "}\n" + >- "public void run() throws IOException {\n" + >- " ServerSocket server = new ServerSocket(this.portNumber);\n" + >- " this.socket = server.accept();\n" + >- " this.socket.setTcpNoDelay(true);\n" + >- " server.close();\n" + >- "\n" + >- " DataInputStream in = new DataInputStream(this.socket.getInputStream());\n" + >- " final DataOutputStream out = new DataOutputStream(this.socket.getOutputStream());\n" + >- " while (true) {\n" + >- " final String className = in.readUTF();\n" + >- " Thread thread = new Thread() {\n" + >- " public void run() {\n" + >- " try {\n" + >- " loadAndRun(className);\n" + >- " out.writeBoolean(true);\n" + >- " System.err.println(VerifyTests.class.getName());\n" + >- " System.out.println(VerifyTests.class.getName());\n" + >- " } catch (Throwable e) {\n" + >- " e.printStackTrace();\n" + >- " try {\n" + >- " System.err.println(VerifyTests.class.getName());\n" + >- " System.out.println(VerifyTests.class.getName());\n" + >- " out.writeBoolean(false);\n" + >- " } catch (IOException e1) {\n" + >- " // ignore\n" + >- " }\n" + >- " }\n" + >- " }\n" + >- " };\n" + >- " thread.start();\n" + >- " }\n" + >- "}\n" + >- "}\n"; >+ "/*******************************************************************************\n" + >+ " * Copyright (c) 2000, 2011 IBM Corporation and others.\n" + >+ " * All rights reserved. This program and the accompanying materials\n" + >+ " * are made available under the terms of the Eclipse Public License v1.0\n" + >+ " * which accompanies this distribution, and is available at\n" + >+ " * http://www.eclipse.org/legal/epl-v10.html\n" + >+ " *\n" + >+ " * Contributors:\n" + >+ " * IBM Corporation - initial API and implementation\n" + >+ " *******************************************************************************/\n" + >+ "package org.eclipse.jdt.core.tests.util;\n" + >+ "\n" + >+ "import java.io.DataInputStream;\n" + >+ "import java.io.DataOutputStream;\n" + >+ "import java.io.File;\n" + >+ "import java.io.FileInputStream;\n" + >+ "import java.io.FileNotFoundException;\n" + >+ "import java.io.IOException;\n" + >+ "import java.io.InputStream;\n" + >+ "import java.lang.reflect.InvocationTargetException;\n" + >+ "import java.lang.reflect.Method;\n" + >+ "import java.net.ServerSocket;\n" + >+ "import java.net.Socket;\n" + >+ "import java.util.StringTokenizer;\n" + >+ "\n" + >+ "/******************************************************\n" + >+ " *\n" + >+ " * IMPORTANT NOTE: If modifying this class, copy the source to TestVerifier#getVerifyTestsCode()\n" + >+ " * (see this method for details)\n" + >+ " *\n" + >+ " ******************************************************/\n" + >+ "\n" + >+ "public class VerifyTests {\n" + >+ " int portNumber;\n" + >+ " Socket socket;\n" + >+ "\n" + >+ "/**\n" + >+ " * NOTE: Code copied from junit.util.TestCaseClassLoader.\n" + >+ " *\n" + >+ " * A custom class loader which enables the reloading\n" + >+ " * of classes for each test run. The class loader\n" + >+ " * can be configured with a list of package paths that\n" + >+ " * should be excluded from loading. The loading\n" + >+ " * of these packages is delegated to the system class\n" + >+ " * loader. They will be shared across test runs.\n" + >+ " * <p>\n" + >+ " * The list of excluded package paths is specified in\n" + >+ " * a properties file \"excluded.properties\" that is located in\n" + >+ " * the same place as the TestCaseClassLoader class.\n" + >+ " * <p>\n" + >+ " * <b>Known limitation:</b> the VerifyClassLoader cannot load classes\n" + >+ " * from jar files.\n" + >+ " */\n" + >+ "\n" + >+ "\n" + >+ "public class VerifyClassLoader extends ClassLoader {\n" + >+ " /** scanned class path */\n" + >+ " private String[] pathItems;\n" + >+ "\n" + >+ " /** excluded paths */\n" + >+ " private String[] excluded= {};\n" + >+ "\n" + >+ " /**\n" + >+ " * Constructs a VerifyClassLoader. It scans the class path\n" + >+ " * and the excluded package paths\n" + >+ " */\n" + >+ " public VerifyClassLoader() {\n" + >+ " super();\n" + >+ " String classPath= System.getProperty(\"java.class.path\");\n" + >+ " String separator= System.getProperty(\"path.separator\");\n" + >+ "\n" + >+ " // first pass: count elements\n" + >+ " StringTokenizer st= new StringTokenizer(classPath, separator);\n" + >+ " int i= 0;\n" + >+ " while (st.hasMoreTokens()) {\n" + >+ " st.nextToken();\n" + >+ " i++;\n" + >+ " }\n" + >+ " // second pass: split\n" + >+ " this.pathItems= new String[i];\n" + >+ " st= new StringTokenizer(classPath, separator);\n" + >+ " i= 0;\n" + >+ " while (st.hasMoreTokens()) {\n" + >+ " this.pathItems[i++]= st.nextToken();\n" + >+ " }\n" + >+ "\n" + >+ " }\n" + >+ " public java.net.URL getResource(String name) {\n" + >+ " return ClassLoader.getSystemResource(name);\n" + >+ " }\n" + >+ " public InputStream getResourceAsStream(String name) {\n" + >+ " return ClassLoader.getSystemResourceAsStream(name);\n" + >+ " }\n" + >+ " protected boolean isExcluded(String name) {\n" + >+ " // exclude the \"java\" packages.\n" + >+ " // They always need to be excluded so that they are loaded by the system class loader\n" + >+ " if (name.startsWith(\"java\"))\n" + >+ " return true;\n" + >+ "\n" + >+ " // exclude the user defined package paths\n" + >+ " for (int i= 0; i < this.excluded.length; i++) {\n" + >+ " if (name.startsWith(this.excluded[i])) {\n" + >+ " return true;\n" + >+ " }\n" + >+ " }\n" + >+ " return false;\n" + >+ " }\n" + >+ " public synchronized Class loadClass(String name, boolean resolve)\n" + >+ " throws ClassNotFoundException {\n" + >+ "\n" + >+ " Class c= findLoadedClass(name);\n" + >+ " if (c != null)\n" + >+ " return c;\n" + >+ " //\n" + >+ " // Delegate the loading of excluded classes to the\n" + >+ " // standard class loader.\n" + >+ " //\n" + >+ " if (isExcluded(name)) {\n" + >+ " try {\n" + >+ " c= findSystemClass(name);\n" + >+ " return c;\n" + >+ " } catch (ClassNotFoundException e) {\n" + >+ " // keep searching\n" + >+ " }\n" + >+ " }\n" + >+ " File file= locate(name);\n" + >+ " if (file == null)\n" + >+ " throw new ClassNotFoundException();\n" + >+ " byte data[]= loadClassData(file);\n" + >+ " c= defineClass(name, data, 0, data.length);\n" + >+ " if (resolve)\n" + >+ " resolveClass(c);\n" + >+ " return c;\n" + >+ " }\n" + >+ " private byte[] loadClassData(File f) throws ClassNotFoundException {\n" + >+ " FileInputStream stream = null;\n" + >+ " try {\n" + >+ " //System.out.println(\"loading: \"+f.getPath());\n" + >+ " stream = new FileInputStream(f);\n" + >+ "\n" + >+ " try {\n" + >+ " byte[] b= new byte[stream.available()];\n" + >+ " stream.read(b);\n" + >+ " return b;\n" + >+ " }\n" + >+ " catch (IOException e) {\n" + >+ " throw new ClassNotFoundException();\n" + >+ " }\n" + >+ " }\n" + >+ " catch (FileNotFoundException e) {\n" + >+ " throw new ClassNotFoundException();\n" + >+ " } finally {\n" + >+ " if (stream != null) {\n" + >+ " try {\n" + >+ " stream.close();\n" + >+ " } catch (IOException e) {\n" + >+ " /* ignore */\n" + >+ " }\n" + >+ " }\n" + >+ " }\n" + >+ " }\n" + >+ " /**\n" + >+ " * Locate the given file.\n" + >+ " * @return Returns null if file couldn't be found.\n" + >+ " */\n" + >+ " private File locate(String fileName) {\n" + >+ " if (fileName != null) {\n" + >+ " fileName= fileName.replace('.', '/')+\".class\";\n" + >+ " File path= null;\n" + >+ " for (int i= 0; i < this.pathItems.length; i++) {\n" + >+ " path= new File(this.pathItems[i], fileName);\n" + >+ " if (path.exists())\n" + >+ " return path;\n" + >+ " }\n" + >+ " }\n" + >+ " return null;\n" + >+ " }\n" + >+ "}\n" + >+ "\n" + >+ "public void loadAndRun(String className) throws Throwable {\n" + >+ " //System.out.println(\"Loading \" + className + \"...\");\n" + >+ " Class testClass = new VerifyClassLoader().loadClass(className);\n" + >+ " //System.out.println(\"Loaded \" + className);\n" + >+ " try {\n" + >+ " Method main = testClass.getMethod(\"main\", new Class[] {String[].class});\n" + >+ " //System.out.println(\"Running \" + className);\n" + >+ " main.invoke(null, new Object[] {new String[] {}});\n" + >+ " //System.out.println(\"Finished running \" + className);\n" + >+ " } catch (NoSuchMethodException e) {\n" + >+ " return;\n" + >+ " } catch (InvocationTargetException e) {\n" + >+ " throw e.getTargetException();\n" + >+ " }\n" + >+ "}\n" + >+ "public static void main(String[] args) throws IOException {\n" + >+ " VerifyTests verify = new VerifyTests();\n" + >+ " verify.portNumber = Integer.parseInt(args[0]);\n" + >+ " verify.run();\n" + >+ "}\n" + >+ "public void run() throws IOException {\n" + >+ " ServerSocket server = new ServerSocket(this.portNumber);\n" + >+ " this.socket = server.accept();\n" + >+ " this.socket.setTcpNoDelay(true);\n" + >+ " server.close();\n" + >+ "\n" + >+ " DataInputStream in = new DataInputStream(this.socket.getInputStream());\n" + >+ " final DataOutputStream out = new DataOutputStream(this.socket.getOutputStream());\n" + >+ " while (true) {\n" + >+ " final String className = in.readUTF();\n" + >+ " Thread thread = new Thread() {\n" + >+ " public void run() {\n" + >+ " try {\n" + >+ " loadAndRun(className);\n" + >+ " out.writeBoolean(true);\n" + >+ " System.err.println(VerifyTests.class.getName());\n" + >+ " System.out.println(VerifyTests.class.getName());\n" + >+ " } catch (Throwable e) {\n" + >+ " e.printStackTrace();\n" + >+ " try {\n" + >+ " System.err.println(VerifyTests.class.getName());\n" + >+ " System.out.println(VerifyTests.class.getName());\n" + >+ " out.writeBoolean(false);\n" + >+ " } catch (IOException e1) {\n" + >+ " e1.printStackTrace();\n" + >+ " }\n" + >+ " }\n" + >+ " try {\n" + >+ " out.flush();\n" + >+ " } catch (IOException e) {\n" + >+ " e.printStackTrace();\n" + >+ " }\n" + >+ " }\n" + >+ " };\n" + >+ " thread.start();\n" + >+ " }\n" + >+ "}\n" + >+ "}"; > } > private void launchAndRun(String className, String[] classpaths, String[] programArguments, String[] vmArguments) { > // we won't reuse the vm, shut the existing one if running >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/Util.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/Util.java >index 8b41712..70415af 100644 >--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/Util.java >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/Util.java >@@ -1348,6 +1348,34 @@ > } > } > } >+ >+/** >+ * Zips the given files into the given jar. All the files are kept at the root of the zip. >+ */ >+public static void zipFiles(File[] files, String zipPath) throws IOException { >+ File zipFile = new File(zipPath); >+ if (zipFile.exists()) { >+ if (!delete(zipFile)) >+ throw new IOException("Could not delete " + zipPath); >+ // ensure the new zip file has a different timestamp than the previous one >+ int timeToWait = 1000; // some platform (like Linux) have a 1s granularity) >+ waitAtLeast(timeToWait); >+ } else { >+ zipFile.getParentFile().mkdirs(); >+ } >+ ZipOutputStream zip = new ZipOutputStream(new FileOutputStream(zipFile)); >+ try { >+ for (int i = 0, length = files.length; i < length; i++) { >+ File file = files[i]; >+ ZipEntry entry = new ZipEntry(file.getName()); >+ zip.putNextEntry(entry); >+ zip.write(org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(file)); >+ zip.closeEntry(); >+ } >+ } finally { >+ zip.close(); >+ } >+} > /** > * Returns the compilation errors / warnings for the given CompilationResult. > * >diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/VerifyTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/VerifyTests.java >index 5a65937..45404f9 100644 >--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/VerifyTests.java >+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/VerifyTests.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -10,10 +10,18 @@ > *******************************************************************************/ > package org.eclipse.jdt.core.tests.util; > >-import java.lang.reflect.*; >-import java.io.*; >-import java.net.*; >-import java.util.*; >+import java.io.DataInputStream; >+import java.io.DataOutputStream; >+import java.io.File; >+import java.io.FileInputStream; >+import java.io.FileNotFoundException; >+import java.io.IOException; >+import java.io.InputStream; >+import java.lang.reflect.InvocationTargetException; >+import java.lang.reflect.Method; >+import java.net.ServerSocket; >+import java.net.Socket; >+import java.util.StringTokenizer; > > /****************************************************** > * >diff --git a/org.eclipse.jdt.core.tests.compiler/test.xml b/org.eclipse.jdt.core.tests.compiler/test.xml >index ced0efe..c6bbf1e 100644 >--- a/org.eclipse.jdt.core.tests.compiler/test.xml >+++ b/org.eclipse.jdt.core.tests.compiler/test.xml >@@ -1,6 +1,7 @@ >-<?xml version="1.0"?> >- <!-- >- Copyright (c) 2002, 2009 IBM Corporation and others. >+<?xml version="1.0" encoding="UTF-8"?> >+ >+<!-- >+ Copyright (c) 2002, 2011 IBM Corporation 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 >diff --git a/org.eclipse.jdt.core.tests.compiler/workspace/TestBootstrapMethodAtt.class b/org.eclipse.jdt.core.tests.compiler/workspace/TestBootstrapMethodAtt.class >new file mode 100644 >index 0000000..b2693d7 >--- /dev/null >+++ b/org.eclipse.jdt.core.tests.compiler/workspace/TestBootstrapMethodAtt.class >Binary files differ >diff --git a/org.eclipse.jdt.core.tests.model/.cvsignore b/org.eclipse.jdt.core.tests.model/.cvsignore >deleted file mode 100644 >index c5e82d7..0000000 >--- a/org.eclipse.jdt.core.tests.model/.cvsignore >+++ /dev/null >@@ -1 +0,0 @@ >-bin >\ No newline at end of file >diff --git a/org.eclipse.jdt.core.tests.model/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.jdt.core.tests.model/.settings/org.eclipse.core.runtime.prefs >new file mode 100644 >index 0000000..5a0ad22 >--- /dev/null >+++ b/org.eclipse.jdt.core.tests.model/.settings/org.eclipse.core.runtime.prefs >@@ -0,0 +1,2 @@ >+eclipse.preferences.version=1 >+line.separator=\n >diff --git a/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF b/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF >index 6a7a5b0..4361c6d 100644 >--- a/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF >+++ b/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF >@@ -2,7 +2,7 @@ > Bundle-ManifestVersion: 2 > Bundle-Name: %pluginName > Bundle-SymbolicName: org.eclipse.jdt.core.tests.model;singleton:=true >-Bundle-Version: 3.8.0.qualifier >+Bundle-Version: 3.8.1.qualifier > Bundle-ClassPath: jdtcoretestsmodel.jar > Bundle-Vendor: %providerName > Bundle-Localization: plugin >@@ -23,5 +23,6 @@ > org.eclipse.team.core;bundle-version="[3.2.0,4.0.0)", > org.eclipse.text;bundle-version="[3.2.0,4.0.0)", > com.ibm.icu;bundle-version="3.4.4", >- org.eclipse.core.filesystem;bundle-version="[1.2.0,2.0.0)" >+ org.eclipse.core.filesystem;bundle-version="[1.2.0,2.0.0)", >+ org.eclipse.jdt.annotation;bundle-version="[1.0.0,2.0.0)" > Bundle-RequiredExecutionEnvironment: J2SE-1.4 >diff --git a/org.eclipse.jdt.core.tests.model/plugin.xml b/org.eclipse.jdt.core.tests.model/plugin.xml >index 6cda687..5d8226c 100644 >--- a/org.eclipse.jdt.core.tests.model/plugin.xml >+++ b/org.eclipse.jdt.core.tests.model/plugin.xml >@@ -1,5 +1,6 @@ > <?xml version="1.0" encoding="UTF-8"?> >-<?eclipse version="3.0"?> <!-- >+<?eclipse version="3.0"?> >+<!-- > Copyright (c) 2002, 2009 IBM Corporation and others. > All rights reserved. This program and the accompanying materials > are made available under the terms of the Eclipse Public License v1.0 >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS4Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS4Test.java >index 00678f7..9c7b8e9 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS4Test.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS4Test.java >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contribution for bug 186342 - [compiler][null] Using annotations for null checking > *******************************************************************************/ > package org.eclipse.jdt.core.tests.dom; > >@@ -7475,7 +7476,6 @@ > assertTrue("Not assignement compatible", typeBinding.isAssignmentCompatible(typeBinding2)); > assertTrue("Not assignement compatible", typeBinding.isAssignmentCompatible(collectionTypeBinding)); > } >- > /* > * https://bugs.eclipse.org/bugs/show_bug.cgi?id=156352 > */ >@@ -7494,6 +7494,12 @@ > buffer.append(typeBinding.getAnnotations().length); > typeBinding= typeBinding.getSuperclass(); > } >+ // the right outcome would be "020", but depending on the strategy when exactly >+ // annotations are resolved the annotations on Test2 are (not) present when >+ // traversing the super-class chain. >+ // The patch in https://bugs.eclipse.org/186342#c196 produced "020" but >+ // the previous behavior ("000") was restored in https://bugs.eclipse.org/365387 >+ // (see the change in SourceTypeBinding.resolveTypesFor(..)) > assertEquals("Wrong number of annotations", "000", String.valueOf(buffer)); > } > } >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java >index c6f70e8..fd388a6 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java >@@ -7,7 +7,10 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >- * Stephan Herrmann - Contribution for Bug 342671 - ClassCastException: org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding cannot be cast to org.eclipse.jdt.internal.compiler.lookup.ArrayBinding >+ * Stephan Herrmann - Contributions for >+ * Bug 342671 - ClassCastException: org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding cannot be cast to org.eclipse.jdt.internal.compiler.lookup.ArrayBinding >+ * Bug 353474 - type converters should include more annotations >+ * Bug 186342 - [compiler][null] Using annotations for null checking > *******************************************************************************/ > package org.eclipse.jdt.core.tests.dom; > >@@ -50,7 +53,7 @@ > static { > // TESTS_NUMBERS = new int[] { 353 }; > // TESTS_RANGE = new int[] { 325, -1 }; >-// TESTS_NAMES = new String[] {"test0204"}; >+// TESTS_NAMES = new String[] {"testBug353474"}; > } > public static Test suite() { > return buildModelTestSuite(ASTConverter15Test.class); >@@ -7495,6 +7498,12 @@ > buffer.append(typeBinding.getAnnotations().length); > typeBinding= typeBinding.getSuperclass(); > } >+ // the right outcome would be "020", but depending on the strategy when exactly >+ // annotations are resolved the annotations on Test2 are (not) present when >+ // traversing the super-class chain. >+ // The patch in https://bugs.eclipse.org/186342#c196 produced "020" but >+ // the previous behavior ("000") was restored in https://bugs.eclipse.org/365387 >+ // (see the change in SourceTypeBinding.resolveTypesFor(..)) > assertEquals("Wrong number of annotations", "000", String.valueOf(buffer)); > } > } >@@ -11348,5 +11357,100 @@ > rhsType = ((Assignment)((ExpressionStatement)((Statement) statements.get(1))).getExpression()).getRightHandSide().resolveTypeBinding(); > assertFalse("Assignement compatible", rhsType.isAssignmentCompatible(assignmentType)); > } >+ // Bug 353474 - type converters should include more annotations >+ public void testBug353474() throws CoreException { >+ >+ this.createFolder("/Converter15/src/testBug353474/annot"); >+ String contents = >+ "package testBug353474.annot;\n" + >+ "import static java.lang.annotation.ElementType.*;\n" + >+ "import java.lang.annotation.*;\n" + >+ "@Retention(RetentionPolicy.CLASS)\n" + >+ "@Target({METHOD,PARAMETER,LOCAL_VARIABLE})\n" + >+ "public @interface Nullable {\n" + >+ "}\n"; >+ getWorkingCopy("/Converter15/src/testBug353474/annot/Nullable.java", contents, true/*resolve*/); >+ >+ this.createFolder("/Converter15/src/testBug353474/p1"); >+ contents = >+ "package testBug353474.p1;\n" + >+ "import testBug353474.annot.*;\n" + >+ "public class C1 {\n" + >+ " public @Nullable String foo(@Nullable Object arg) {\n" + >+ " return \"\";\n" + >+ " }\n" + >+ "}\n"; >+ getWorkingCopy("/Converter15/src/testBug353474/p1/C1.java", contents, true/*resolve*/); >+ >+ this.workingCopy = getWorkingCopy("/Converter15/src/testBug353474/p1/C2.java", true/*resolve*/); >+ contents = >+ "package testBug353474.p1;\n" + >+ "public class C2 {\n" + >+ " public String bar(C1 c1) {\n" + >+ " return c1.foo(null);\n" + >+ " }\n" + >+ "}\n"; >+ ASTNode node = buildAST( >+ contents, >+ this.workingCopy, >+ true); >+ assertNotNull("No node", node); >+ assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); >+ CompilationUnit compilationUnit = (CompilationUnit) node; >+ TypeDeclaration c2 = (TypeDeclaration) compilationUnit.types().get(0); >+ MethodDeclaration bar = (MethodDeclaration) c2.bodyDeclarations().get(0); >+ ReturnStatement returnStat = (ReturnStatement) bar.getBody().statements().get(0); >+ MethodInvocation fooCall = (MethodInvocation) returnStat.getExpression(); >+ IMethodBinding resolvedFoo = fooCall.resolveMethodBinding(); >+ IAnnotationBinding[] parameterAnnotations0 = resolvedFoo.getParameterAnnotations(0); >+ assertNotNull("Parameter annotation should not be null", parameterAnnotations0); >+ assertEquals("Should have exactly one annotation", 1, parameterAnnotations0.length); >+ assertEquals("Unexpected annotation name", "Nullable", parameterAnnotations0[0].getName()); >+ >+ IAnnotationBinding[] returnAnnotations = resolvedFoo.getAnnotations(); >+ assertNotNull("Return annotation should not be null", returnAnnotations); >+ assertEquals("Should have exactly one return annotation", 1, returnAnnotations.length); >+ assertEquals("Unexpected annotation name", "Nullable", returnAnnotations[0].getName()); >+ deleteFolder("/Converter15/src/testBug353474"); >+ } >+ // Bug 353474 - type converters should include more annotations >+ // secondary type comes from binary >+ public void testBug353474a() throws CoreException { >+ String jarLocation = getWorkspacePath()+"Converter15/bins/bug353474.jar"; >+ IJavaProject jp = createJavaProject("Bug353464a", new String[]{"src"}, new String[]{"CONVERTER_JCL15_LIB", jarLocation}, "bin", "1.5"); >+ try { >+ this.workingCopy = getWorkingCopy("/Bug353464a/src/testBug353474/p1/C2.java", true/*resolve*/); >+ String contents = >+ "package testBug353474.p1;\n" + >+ "public class C2 {\n" + >+ " public String bar(C1a c1) {\n" + >+ " return c1.foo(null);\n" + >+ " }\n" + >+ "}\n"; >+ ASTNode node = buildAST( >+ contents, >+ this.workingCopy, >+ true); >+ assertNotNull("No node", node); >+ assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType()); >+ CompilationUnit compilationUnit = (CompilationUnit) node; >+ TypeDeclaration c2 = (TypeDeclaration) compilationUnit.types().get(0); >+ MethodDeclaration bar = (MethodDeclaration) c2.bodyDeclarations().get(0); >+ ReturnStatement returnStat = (ReturnStatement) bar.getBody().statements().get(0); >+ MethodInvocation fooCall = (MethodInvocation) returnStat.getExpression(); >+ IMethodBinding resolvedFoo = fooCall.resolveMethodBinding(); >+ IAnnotationBinding[] parameterAnnotations0 = resolvedFoo.getParameterAnnotations(0); >+ assertNotNull("Parameter annotation should not be null", parameterAnnotations0); >+ assertEquals("Should have exactly one annotation", 1, parameterAnnotations0.length); >+ assertEquals("Unexpected annotation name", "Nullable", parameterAnnotations0[0].getName()); >+ >+ IAnnotationBinding[] returnAnnotations = resolvedFoo.getAnnotations(); >+ assertNotNull("Return annotation should not be null", returnAnnotations); >+ assertEquals("Should have exactly one return annotation", 1, returnAnnotations.length); >+ assertEquals("Unexpected annotation name", "Nullable", returnAnnotations[0].getName()); >+ } finally { >+ deleteProject(jp); >+ } >+ } > > } >\ No newline at end of file >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterJavadocTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterJavadocTest.java >index a34e7c8..441bc78 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterJavadocTest.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterJavadocTest.java >@@ -275,11 +275,10 @@ > int c1, c2, c3, c4; > charLength++; > while (source[idx+charLength] == 'u') charLength++; >- if (((c1 = ScannerHelper.getNumericValue(source[idx+charLength++])) > 15 >- || c1 < 0) >- || ((c2 = ScannerHelper.getNumericValue(source[idx+charLength++])) > 15 || c2 < 0) >- || ((c3 = ScannerHelper.getNumericValue(source[idx+charLength++])) > 15 || c3 < 0) >- || ((c4 = ScannerHelper.getNumericValue(source[idx+charLength++])) > 15 || c4 < 0)) { >+ if (((c1 = ScannerHelper.getHexadecimalValue(source[idx+charLength++])) > 15 || c1 < 0) >+ || ((c2 = ScannerHelper.getHexadecimalValue(source[idx+charLength++])) > 15 || c2 < 0) >+ || ((c3 = ScannerHelper.getHexadecimalValue(source[idx+charLength++])) > 15 || c3 < 0) >+ || ((c4 = ScannerHelper.getHexadecimalValue(source[idx+charLength++])) > 15 || c4 < 0)) { > return ch; > } > ch = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4); >@@ -474,11 +473,10 @@ > int c1, c2, c3, c4; > unicodeSource[u++] = source[i]; > unicodeSource[u++] = source[++i]; >- if (((c1 = ScannerHelper.getNumericValue(source[i+1])) > 15 >- || c1 < 0) >- || ((c2 = ScannerHelper.getNumericValue(source[i+2])) > 15 || c2 < 0) >- || ((c3 = ScannerHelper.getNumericValue(source[i+3])) > 15 || c3 < 0) >- || ((c4 = ScannerHelper.getNumericValue(source[i+4])) > 15 || c4 < 0)) { >+ if (((c1 = ScannerHelper.getHexadecimalValue(source[i+1])) > 15 || c1 < 0) >+ || ((c2 = ScannerHelper.getHexadecimalValue(source[i+2])) > 15 || c2 < 0) >+ || ((c3 = ScannerHelper.getHexadecimalValue(source[i+3])) > 15 || c3 < 0) >+ || ((c4 = ScannerHelper.getHexadecimalValue(source[i+4])) > 15 || c4 < 0)) { > throw new RuntimeException("Invalid unicode in source at "+i); > } > for (int j=0; j<4; j++) unicodeSource[u++] = source[++i]; >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST3_2.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST3_2.java >index 080fd86..98199d7 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST3_2.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST3_2.java >@@ -10613,4 +10613,22 @@ > assertEquals("wrong tag name", "@literal", element.getTagName()); > checkSourceRange((TextElement) element.fragments().get(0), " stars**** ", source); > } >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=361938 >+ public void test0722() throws JavaModelException { >+ String source = "public class X {\n" + >+ " X(){\n" + >+ " try {\n" + >+ " }\n" + >+ " finally {\n" + >+ " }\n" + >+ " }\n" + >+ "}\n"; >+ >+ ASTParser parser = ASTParser.newParser(AST.JLS3); >+ parser.setKind(ASTParser.K_COMPILATION_UNIT); >+ parser.setSource(source.toCharArray()); >+ CompilationUnit resultCompilationUnit = (CompilationUnit) parser.createAST(null); >+ Object o = resultCompilationUnit.types().get(0); >+ assertEquals(o.toString(), source); >+ } > } >\ No newline at end of file >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST4_2.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST4_2.java >index e3015a5..3e8435b 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST4_2.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTestAST4_2.java >@@ -122,7 +122,7 @@ > static { > // TESTS_NAMES = new String[] {"test0602"}; > // TESTS_RANGE = new int[] { 721, -1 }; >-// TESTS_NUMBERS = new int[] { 721, 722, 723, 724, 725 }; >+// TESTS_NUMBERS = new int[] { 725 }; > } > public static Test suite() { > return buildModelTestSuite(ASTConverterTestAST4_2.class); >@@ -10641,4 +10641,90 @@ > } > } > } >+ /** >+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=347396 >+ */ >+ public void test0723() { >+ ASTParser parser = ASTParser.newParser(AST.JLS4); >+ parser.setKind (ASTParser.K_STATEMENTS); >+ String src = "int j;\nfor {};\nj=1000;"; >+ char[] source = src.toCharArray(); >+ parser.setStatementsRecovery(true); >+ parser.setSource(source); >+ ASTNode result = parser.createAST (null); >+ assertNotNull("no result", result); >+ assertEquals("Wrong type", ASTNode.BLOCK, result.getNodeType()); >+ Block block = (Block) result; >+ List statements = block.statements(); >+ assertNotNull("No statements", statements); >+ assertEquals("Wrong size", 3, statements.size()); >+ assertFalse(isRecovered((ASTNode) statements.get(0))); >+ assertFalse(isRecovered((ASTNode) statements.get(1))); >+ assertFalse(isRecovered((ASTNode) statements.get(2))); >+ } >+ >+ /** >+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=347396 >+ */ >+ public void test0724() { >+ ASTParser parser = ASTParser.newParser(AST.JLS4); >+ parser.setKind (ASTParser.K_COMPILATION_UNIT); >+ String src = "public class X { void foo() {int j;\nfor {};\nj=1000;}}"; >+ char[] source = src.toCharArray(); >+ parser.setStatementsRecovery(true); >+ parser.setSource(source); >+ ASTNode result = parser.createAST (null); >+ assertNotNull("no result", result); >+ assertEquals("Wrong type", ASTNode.COMPILATION_UNIT, result.getNodeType()); >+ Block block = ((MethodDeclaration) getASTNode((CompilationUnit) result, 0, 0)).getBody(); >+ List statements = block.statements(); >+ assertNotNull("No statements", statements); >+ assertEquals("Wrong size", 3, statements.size()); >+ assertFalse(isRecovered((ASTNode) statements.get(0))); >+ assertFalse(isRecovered((ASTNode) statements.get(1))); >+ assertFalse(isRecovered((ASTNode) statements.get(2))); >+ } >+ /* >+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=357471 >+ */ >+ public void test0725() throws JavaModelException { >+ ICompilationUnit workingCopy = null; >+ try { >+ String contents = >+ "package one.two;\n" + >+ "public class one {}"; >+ workingCopy = getWorkingCopy("/Converter/src/one/two/one.java", true/*resolve*/); >+ CompilationUnit unit = (CompilationUnit) buildAST( >+ AST.JLS3, >+ contents, >+ workingCopy, >+ true, >+ true, >+ true); >+ PackageDeclaration packageDeclaration = unit.getPackage(); >+ IPackageBinding packageBinding = packageDeclaration.resolveBinding(); >+ assertNotNull("No binding", packageBinding); >+ assertEquals("Wrong name", "one.two", packageBinding.getName()); >+ Name packageName = packageDeclaration.getName(); >+ IBinding binding = packageName.resolveBinding(); >+ assertEquals("Wrong type", IBinding.PACKAGE, binding.getKind()); >+ packageBinding = (IPackageBinding) binding; >+ assertEquals("Wrong name", "one.two", packageBinding.getName()); >+ packageName = ((QualifiedName) packageName).getQualifier(); >+ binding = packageName.resolveBinding(); >+ assertEquals("Wrong type", IBinding.PACKAGE, binding.getKind()); >+ packageBinding = (IPackageBinding) binding; >+ assertEquals("Wrong name", "one", packageBinding.getName()); >+ packageName = packageDeclaration.getName(); >+ packageName = ((QualifiedName) packageName).getName(); >+ binding = packageName.resolveBinding(); >+ assertEquals("Wrong type", IBinding.PACKAGE, binding.getKind()); >+ packageBinding = (IPackageBinding) binding; >+ assertEquals("Wrong name", "one.two", packageBinding.getName()); >+ } finally { >+ if (workingCopy != null) { >+ workingCopy.discardWorkingCopy(); >+ } >+ } >+ } > } >\ No newline at end of file >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTTest.java >index 108289b..8970e8f 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTTest.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTTest.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -2092,6 +2092,24 @@ > > assertTrue(x.getDimensions() == 5); > assertTrue(x.getElementType().isPrimitiveType()); >+ final ArrayType x3 = this.ast.newArrayType(x, 2); >+ assertTrue(x3.getDimensions() == 7); >+ >+ try { >+ this.ast.newArrayType(null, 2); >+ } catch(IllegalArgumentException e) { >+ // ignore - expected >+ } >+ try { >+ this.ast.newArrayType(x, 0); >+ } catch(IllegalArgumentException e) { >+ // ignore - expected >+ } >+ try { >+ this.ast.newArrayType(x, 100000); >+ } catch(IllegalArgumentException e) { >+ // ignore - expected >+ } > } > > /** @deprecated using deprecated code */ >@@ -5247,6 +5265,16 @@ > * @deprecated (Uses getLeadingComment() which is deprecated) > */ > public void testTryStatement() { >+ if (this.ast.apiLevel() <= AST.JLS3) { >+ // node type introduced in 4.0 API >+ try { >+ final TryStatement x = this.ast.newTryStatement(); >+ x.resources(); >+ assertTrue("should not be reached if jls level <= JLS3", false); >+ } catch (UnsupportedOperationException e) { >+ // pass >+ } >+ } > long previousCount = this.ast.modificationCount(); > final TryStatement x = this.ast.newTryStatement(); > assertTrue(this.ast.modificationCount() > previousCount); >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java >index edb9c06..00bfe17 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java >@@ -62,7 +62,7 @@ > Map formatterOptions; > > static { >-// TESTS_NUMBERS = new int[] { 776, 777, 778, 779,780,781 }; >+// TESTS_NUMBERS = new int[] { 783 }; > // TESTS_RANGE = new int[] { 734, -1 }; > } > public static Test suite() { >@@ -12861,4 +12861,22 @@ > "}" > ); > } >+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=359646 >+public void test783() throws Exception { >+ this.formatterPrefs = null; >+ String source = >+ "public class X {public static void main(String[] args) {\n" + >+ " long x = 0x8000000000000000L;\n" + >+ " System.out.println(x);\n" + >+ " }\n" + >+ "}"; >+ formatSource(source, >+ "public class X {\n" + >+ " public static void main(String[] args) {\n" + >+ " long x = 0x8000000000000000L;\n" + >+ " System.out.println(x);\n" + >+ " }\n" + >+ "}" >+ ); >+} > } >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java >index a616ecd..37eddcd 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -2922,13 +2922,6 @@ > return org.eclipse.jdt.core.tests.util.Util.toString(strings, false/*don't add extra new line*/); > } > protected void tearDown() throws Exception { >- if (JavaModelManager.DEBUG_302850) { >- System.out.println(" - Options before tear down:"); >- System.out.println(" + Task tags: " + JavaCore.getOption(JavaCore.COMPILER_TASK_TAGS)); >- System.out.println(" + Task priorities: " + JavaCore.getOption(JavaCore.COMPILER_TASK_PRIORITIES)); >- System.out.println(" + Forbidden reference: " + JavaCore.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE)); >- System.out.println(org.eclipse.jdt.core.tests.util.Util.indentString(new CompilerOptions(JavaCore.getOptions()).toString(), 2)); >- } > > super.tearDown(); > if (this.workingCopies != null) { >@@ -2937,17 +2930,6 @@ > } > this.wcOwner = null; > >- if (JavaModelManager.DEBUG_302850) { >- System.out.println(" - Options before comparison with defaults:"); >- System.out.println(" + Task tags: " + JavaCore.getOption(JavaCore.COMPILER_TASK_TAGS)); >- System.out.println(" + Task priorities: " + JavaCore.getOption(JavaCore.COMPILER_TASK_PRIORITIES)); >- System.out.println(" + Forbidden reference: " + JavaCore.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE)); >- System.out.println(org.eclipse.jdt.core.tests.util.Util.indentString(new CompilerOptions(JavaCore.getOptions()).toString(), 2)); >- System.out.println(" - Default Options before comparison:"); >- System.out.println(org.eclipse.jdt.core.tests.util.Util.indentString(new CompilerOptions(JavaCore.getDefaultOptions()).toString(), 2)); >- System.out.println("================================================================================"); >- } >- > // ensure workspace options have been restored to their default > Hashtable options = JavaCore.getOptions(); > Hashtable defaultOptions = JavaCore.getDefaultOptions(); >@@ -2955,8 +2937,6 @@ > "Workspace options should be back to their default", > new CompilerOptions(defaultOptions).toString(), > new CompilerOptions(options).toString()); >- >- JavaModelManager.DEBUG_302850 = false; > } > > /** >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java >index d3e6b2b..e33db13 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -130,6 +130,9 @@ > // Access restrictions tests > AccessRestrictionsTests.class, > >+ // Ignore optional problems from source folders tests >+ IgnoreOptionalProblemsFromSourceFoldersTests.class, >+ > // Signature tests > SignatureTests.class, > >@@ -185,6 +188,9 @@ > UtilTests.class, > > JavaCoreOptionsTests.class, >+ >+ // Tests regarding null-annotations: >+ NullAnnotationModelTests.class, > }; > > Class[] deprecatedClasses = getDeprecatedJDOMTestClasses(); >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachSourceTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachSourceTests.java >index 0d6ad4d..26a62e1 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachSourceTests.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachSourceTests.java >@@ -10,6 +10,7 @@ > *******************************************************************************/ > package org.eclipse.jdt.core.tests.model; > >+import java.io.BufferedInputStream; > import java.io.File; > import java.io.FileOutputStream; > import java.io.IOException; >@@ -50,6 +51,7 @@ > import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; > import org.eclipse.jdt.internal.core.ExternalFoldersManager; > import org.eclipse.jdt.internal.core.JarPackageFragmentRoot; >+import org.eclipse.jdt.internal.core.JavaModelManager; > import org.eclipse.jdt.internal.core.JavaProject; > import org.eclipse.jdt.internal.core.util.Util; > >@@ -499,11 +501,39 @@ > "}" > }; > org.eclipse.jdt.core.tests.util.Util.createSourceDir(pathsAndContents, externalFolder + "/src228639/src"); >+ > createExternalFolder("externalFolder/src228639/META-INF"); > createExternalFolder("externalFolder/lib/META-INF"); > > String externalLib = externalFolder + "/lib"; >- IJavaProject javaProject = createJavaProject("P", new String[0], new String[] {externalLib}, ""); >+ IJavaProject javaProject = null; >+ try { >+ javaProject = createJavaProject("P", new String[0], new String[] {externalLib}, ""); >+ } >+ catch (Exception e) { >+ IFolder folder = getFolder(externalLib); >+ System.out.println("---------- This information is logged for debugging purposes as this test fails sporadically.---------"); >+ System.out.println("Failing when creating Link folder for: " + externalFolder); >+ System.out.println("Existing? " + folder.exists()); >+ IProject externalFolderProject = JavaModelManager.getExternalManager().getExternalFoldersProject(); >+ IFile externalProjectFile = externalFolderProject.getFile(".project"); >+ if (externalProjectFile.exists()) { >+ System.out.println("External Folder Project exists with following content:"); >+ BufferedInputStream bs = new BufferedInputStream(externalProjectFile.getContents()); >+ int available = 0; >+ while ((available = bs.available()) > 0) { >+ byte[] contents = new byte[available]; >+ bs.read(contents); >+ System.out.println(new String(contents)); >+ } >+ bs.close(); >+ } >+ else { >+ System.out.println("External folders project doesn't exist."); >+ } >+ System.out.println("---------- Debug information ends ---------"); >+ throw e; >+ } > IPackageFragmentRoot root = javaProject.getPackageFragmentRoot(externalLib); > attachSource(root, externalFolder + "/src228639", ""); > IType type = root.getPackageFragment("p").getClassFile("X.class").getType(); >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachedJavadocTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachedJavadocTests.java >index e68746f..f906062 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachedJavadocTests.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachedJavadocTests.java >@@ -86,6 +86,7 @@ > suite.addTest(new AttachedJavadocTests("testBug334652_3")); > suite.addTest(new AttachedJavadocTests("testBug334652_4")); > suite.addTest(new AttachedJavadocTests("testBug354766")); >+ suite.addTest(new AttachedJavadocTests("testBug354766_2")); > return suite; > } > >@@ -1004,4 +1005,43 @@ > this.project.setRawClasspath(entries, null); > } > } >+ //https://bugs.eclipse.org/bugs/show_bug.cgi?id=354766 >+ public void testBug354766_2() throws CoreException, IOException { >+ IClasspathEntry[] entries = this.project.getRawClasspath(); >+ >+ try { >+ IClasspathAttribute attribute = >+ JavaCore.newClasspathAttribute( >+ IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME, >+ "jar:platform:/resource/AttachedJavadocProject/bug354766_doc.zip!/"); >+ IClasspathEntry newEntry = JavaCore.newLibraryEntry(new Path("/AttachedJavadocProject/bug354766.jar"), null, null, null, new IClasspathAttribute[] { attribute}, false); >+ this.project.setRawClasspath(new IClasspathEntry[]{newEntry}, null); >+ this.project.getResolvedClasspath(false); >+ >+ IPackageFragmentRoot jarRoot = this.project.getPackageFragmentRoot(getFile("/AttachedJavadocProject/bug354766.jar")); >+ final IType type = jarRoot.getPackageFragment("com.test").getClassFile("PublicAbstractClass$InnerFinalException.class").getType(); >+ IMethod method = type.getMethod("InnerFinalException", new String[] { "Lcom.test.PublicAbstractClass;"}); >+ assertNotNull(method); >+ assertTrue("Does not exist", method.exists()); >+ >+ String javadoc = method.getAttachedJavadoc(null); >+ assertNotNull(javadoc); >+ assertEquals( >+ "Wrong contents", >+ "<H3>\r\n" + >+ "PublicAbstractClass.InnerFinalException</H3>\r\n" + >+ "<PRE>\r\n" + >+ "public <B>PublicAbstractClass.InnerFinalException</B>()</PRE>\r\n" + >+ "<DL>\r\n" + >+ "<DD>javadoc for InnerFinalException()\r\n" + >+ "<P>\r\n" + >+ "</DL>\r\n" + >+ "\r\n" + >+ "<!-- ============ METHOD DETAIL ========== -->\r\n" + >+ "\r\n", >+ javadoc); >+ } finally { >+ this.project.setRawClasspath(entries, null); >+ } >+ } > } >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java >index 4166cb2..77a5b58 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,6 +7,8 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Terry Parker <tparker@google.com> - DeltaProcessor misses state changes in archive files, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=357425, >+ * Fup of 357425: ensure all reported regressions are witnessed by tests, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=361922 > *******************************************************************************/ > package org.eclipse.jdt.core.tests.model; > >@@ -67,9 +69,12 @@ > import org.eclipse.jdt.internal.core.JavaModelManager; > import org.eclipse.jdt.internal.core.JavaProject; > import org.eclipse.jdt.internal.core.UserLibraryClasspathContainer; >+import org.eclipse.jdt.internal.core.builder.State; > import org.eclipse.team.core.RepositoryProvider; > > public class ClasspathTests extends ModifyingResourceTests { >+ private static final IClasspathAttribute ATTR_IGNORE_OPTIONAL_PROBLEMS_TRUE = JavaCore.newClasspathAttribute(IClasspathAttribute.IGNORE_OPTIONAL_PROBLEMS, "true"); >+ private static final IClasspathAttribute ATTR_IGNORE_OPTIONAL_PROBLEMS_FALSE = JavaCore.newClasspathAttribute(IClasspathAttribute.IGNORE_OPTIONAL_PROBLEMS, "false"); > > public class TestContainer implements IClasspathContainer { > IPath path; >@@ -249,6 +254,7 @@ > suite.addTest(new ClasspathTests("testInvalidClasspath2")); > suite.addTest(new ClasspathTests("testInvalidExternalClassFolder")); > suite.addTest(new ClasspathTests("testInvalidExternalJar")); >+ suite.addTest(new ClasspathTests("testTransitionFromInvalidToValidJar")); > suite.addTest(new ClasspathTests("testInvalidInternalJar1")); > suite.addTest(new ClasspathTests("testInvalidInternalJar2")); > suite.addTest(new ClasspathTests("testInvalidSourceFolder")); >@@ -334,6 +340,10 @@ > suite.addTest(new ClasspathTests("testBug321170")); > suite.addTest(new ClasspathTests("testBug229042")); > suite.addTest(new ClasspathTests("testBug274737")); >+ suite.addTest(new ClasspathTests("testBug357425")); >+ suite.addTest(new ClasspathTests("testBug287164")); >+ suite.addTest(new ClasspathTests("testBug220928a")); >+ suite.addTest(new ClasspathTests("testBug220928b")); > return suite; > } > public void setUpSuite() throws Exception { >@@ -2020,6 +2030,7 @@ > public void testClasspathValidation22() throws CoreException { > try { > IJavaProject proj = this.createJavaProject("P", new String[] {}, ""); >+ proj.setOption(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, JavaCore.ERROR); > IClasspathEntry[] originalCP = proj.getRawClasspath(); > > IClasspathEntry[] newCP = new IClasspathEntry[originalCP.length+2]; >@@ -2045,6 +2056,7 @@ > public void testClasspathValidation23() throws CoreException { > try { > IJavaProject proj = this.createJavaProject("P", new String[] {}, ""); >+ proj.setOption(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, JavaCore.IGNORE); > IClasspathEntry[] originalCP = proj.getRawClasspath(); > > IClasspathEntry[] newCP = new IClasspathEntry[originalCP.length+2]; >@@ -4197,6 +4209,43 @@ > "Project 'P' is missing required library: \'" + jarPath + "\'", > proj); > } finally { >+ deleteProject("P"); >+ } >+} >+/* >+ * Ensures that validateClasspathEntry() sees a transition from an invalid/missing jar to a valid jar. >+ */ >+public void testTransitionFromInvalidToValidJar() throws CoreException, IOException { >+ String transitioningJarName = "transitioningJar.jar"; >+ String transitioningJar = getExternalPath() + transitioningJarName; >+ String invalidJar = getExternalPath() + "invalidJar.jar"; >+ IClasspathEntry transitioningEntry = JavaCore.newLibraryEntry(new Path(transitioningJar), null, null); >+ IClasspathEntry nonExistingEntry = JavaCore.newLibraryEntry(new Path(invalidJar), null, null); >+ >+ try { >+ Util.createFile(transitioningJar, ""); >+ Util.createFile(invalidJar, ""); >+ IJavaProject proj = createJavaProject("P", new String[] {}, new String[] {transitioningJar, invalidJar}, "bin"); >+ >+ IJavaModelStatus status1 = ClasspathEntry.validateClasspathEntry(proj, transitioningEntry, false, false); >+ IJavaModelStatus status2 = ClasspathEntry.validateClasspathEntry(proj, nonExistingEntry, false, false); >+ assertFalse("Non-existing jar should be invalid", status1.isOK()); >+ assertFalse("Non-existing jar should be invalid", status2.isOK()); >+ >+ Util.createJar( >+ new String[0], >+ new String[] { >+ "META-INF/MANIFEST.MF", >+ "Manifest-Version: 1.0\n" >+ }, >+ transitioningJar, >+ JavaCore.VERSION_1_4); >+ status1 = ClasspathEntry.validateClasspathEntry(proj, transitioningEntry, false, false); >+ status2 = ClasspathEntry.validateClasspathEntry(proj, nonExistingEntry, false, false); >+ assertTrue("Existing jar should be valid", status1.isOK()); >+ assertFalse("Non-existing jar should be invalid", status2.isOK()); >+ } finally { >+ deleteExternalResource(transitioningJarName); > deleteProject("P"); > } > } >@@ -7190,4 +7239,185 @@ > } > } > >+/* >+ * Ensures that the correct delta is reported when changing the Class-Path: clause >+ * of an external jar from not containing a chained jar to containing a chained jar. >+ * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=357425) >+ */ >+public void testBug357425() throws Exception { >+ try { >+ IJavaProject p = createJavaProject("P"); >+ addExternalLibrary(p, getExternalResourcePath("lib357425_a.jar"), new String[0], >+ new String[] { >+ "META-INF/MANIFEST.MF", >+ "Manifest-Version: 1.0\n" >+ }, >+ JavaCore.VERSION_1_4); >+ refreshExternalArchives(p); >+ >+ startDeltas(); >+ org.eclipse.jdt.core.tests.util.Util.createJar(new String[0], >+ new String[] { >+ "META-INF/MANIFEST.MF", >+ "Manifest-Version: 1.0\n" + >+ "Class-Path: lib357425_b.jar\n", >+ }, >+ getExternalResourcePath("lib357425_a.jar"), >+ JavaCore.VERSION_1_4); >+ createExternalFile("lib357425_b.jar", ""); >+ >+ refreshExternalArchives(p); >+ assertDeltas( >+ "Unexpected delta", >+ "P[*]: {CHILDREN | RESOLVED CLASSPATH CHANGED}\n" + >+ " "+ getExternalPath() + "lib357425_a.jar[*]: {CONTENT | REORDERED | ARCHIVE CONTENT CHANGED}\n" + >+ " "+ getExternalPath() + "lib357425_b.jar[+]: {}" >+ ); >+ } finally { >+ stopDeltas(); >+ deleteProject("P"); >+ deleteExternalResource("lib357425_a.jar"); >+ deleteExternalResource("lib357425_b.jar"); >+ } >+} >+/** >+ * @bug287164: Report build path error if source folder has other source folder as output folder >+ * >+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=287164" >+ */ >+public void testBug287164() throws CoreException { >+ try { >+ IJavaProject proj = this.createJavaProject("P", new String[] {}, ""); >+ >+ // Test that with the option set to IGNORE, the Java model status returns OK >+ proj.setOption(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, JavaCore.IGNORE); >+ IClasspathEntry[] originalCP = proj.getRawClasspath(); >+ >+ IClasspathEntry[] newCP = new IClasspathEntry[originalCP.length+2]; >+ System.arraycopy(originalCP, 0, newCP, 0, originalCP.length); >+ newCP[originalCP.length] = JavaCore.newSourceEntry(new Path("/P/src"), new IPath[0], new Path("/P/src2")); >+ newCP[originalCP.length+1] = JavaCore.newSourceEntry(new Path("/P/src2"), new IPath[0], new Path("/P/src")); >+ >+ createFolder("/P/src"); >+ createFolder("/P/src2"); >+ >+ IJavaModelStatus status = JavaConventions.validateClasspath(proj, newCP, proj.getOutputLocation()); >+ assertTrue(status.isOK()); >+ assertStatus( >+ "OK", >+ status); >+ >+ proj.setRawClasspath(newCP, null); >+ assertMarkers("Unexpected markers", "", proj); >+ >+ // Test that with the option set to WARNING, status.isOK() returns true >+ proj.setOption(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, JavaCore.WARNING); >+ >+ status = JavaConventions.validateClasspath(proj, newCP, proj.getOutputLocation()); >+ assertTrue(status.isOK()); >+ assertStatus( >+ "Source folder \'src\' in project \'P\' cannot output to distinct source folder \'src2\'", >+ status); >+ >+ assertMarkers("Unexpected markers", >+ "Source folder \'src\' in project \'P\' cannot output to distinct source folder \'src2\'", proj); >+ >+ // Test that with the option set to WARNING and the presence of a more severe error scenario, the error status >+ // is returned >+ IClasspathEntry[] newCP2 = new IClasspathEntry[newCP.length+1]; >+ System.arraycopy(newCP, 0, newCP2, 0, newCP.length-1); >+ newCP2[newCP.length] = JavaCore.newLibraryEntry(new Path("/P/lib2"), null, null); >+ newCP2[newCP.length-1] = JavaCore.newSourceEntry(new Path("/P/src2"), new IPath[0], new Path("/P/lib2")); >+ >+ status = JavaConventions.validateClasspath(proj, newCP2, proj.getOutputLocation()); >+ assertFalse(status.isOK()); >+ assertStatus( >+ "Source folder \'src2\' in project 'P' cannot output to library \'lib2\'", >+ status); >+ >+ proj.setOption(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, JavaCore.ERROR); >+ >+ status = JavaConventions.validateClasspath(proj, newCP, proj.getOutputLocation()); >+ assertStatus( >+ "Source folder \'src\' in project \'P\' cannot output to distinct source folder \'src2\'", >+ status); >+ >+ } finally { >+ this.deleteProject("P"); >+ } >+} >+ >+/** >+ * @bug220928: [buildpath] Should be able to ignore warnings from certain source folders >+ * >+ * Verify that adding the {@link IClasspathAttribute#IGNORE_OPTIONAL_PROBLEMS} attribute is >+ * correctly reflected by the {@link ClasspathEntry#ignoreOptionalProblems()} method. >+ * >+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=220928" >+ */ >+public void testBug220928a() throws CoreException { >+ ClasspathEntry entry; >+ >+ entry = (ClasspathEntry) JavaCore.newSourceEntry(new Path("/P/src")); >+ assertFalse(entry.ignoreOptionalProblems()); >+ >+ entry = (ClasspathEntry) JavaCore.newSourceEntry(new Path("/P/src"), null, null, null, >+ new IClasspathAttribute[] { ATTR_IGNORE_OPTIONAL_PROBLEMS_TRUE }); >+ assertTrue(entry.ignoreOptionalProblems()); >+ >+ entry = (ClasspathEntry) JavaCore.newSourceEntry(new Path("/P/src"), null, null, null, >+ new IClasspathAttribute[] { ATTR_IGNORE_OPTIONAL_PROBLEMS_FALSE }); >+ assertFalse(entry.ignoreOptionalProblems()); >+} >+ >+/** >+ * @bug220928: [buildpath] Should be able to ignore warnings from certain source folders >+ * >+ * Verify that value of the {@link IClasspathAttribute#IGNORE_OPTIONAL_PROBLEMS} attribute is >+ * correctly saved on workspace save. >+ * >+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=220928" >+ */ >+public void testBug220928b() throws CoreException { >+ boolean autoBuild = getWorkspace().isAutoBuilding(); >+ IWorkspaceDescription preferences = getWorkspace().getDescription(); >+ try { >+ // ensure that the workspace auto-build is ON >+ preferences.setAutoBuilding(true); >+ getWorkspace().setDescription(preferences); >+ >+ IJavaProject project = createJavaProject("P", new String[] {}, "bin"); >+ createFolder("/P/src"); >+ IClasspathEntry[] originalCP = project.getRawClasspath(); >+ IClasspathEntry[] newCP = new IClasspathEntry[originalCP.length + 1]; >+ State state; >+ >+ System.arraycopy(originalCP, 0, newCP, 0, originalCP.length); >+ newCP[originalCP.length] = JavaCore.newSourceEntry(new Path("/P/src")); >+ getJavaProject("P").setRawClasspath(newCP, null); >+ simulateExitRestart(); >+ state = (State) JavaModelManager.getJavaModelManager().getLastBuiltState(getJavaProject("P").getProject(), null); >+ assertFalse(state.sourceLocations[0].ignoreOptionalProblems); >+ >+ System.arraycopy(originalCP, 0, newCP, 0, originalCP.length); >+ newCP[originalCP.length] = JavaCore.newSourceEntry(new Path("/P/src"), null, null, null, >+ new IClasspathAttribute[] { ATTR_IGNORE_OPTIONAL_PROBLEMS_TRUE }); >+ getJavaProject("P").setRawClasspath(newCP, null); >+ simulateExitRestart(); >+ state = (State) JavaModelManager.getJavaModelManager().getLastBuiltState(getJavaProject("P").getProject(), null); >+ assertTrue(state.sourceLocations[0].ignoreOptionalProblems); >+ >+ System.arraycopy(originalCP, 0, newCP, 0, originalCP.length); >+ newCP[originalCP.length] = JavaCore.newSourceEntry(new Path("/P/src"), null, null, null, >+ new IClasspathAttribute[] { ATTR_IGNORE_OPTIONAL_PROBLEMS_FALSE }); >+ getJavaProject("P").setRawClasspath(newCP, null); >+ simulateExitRestart(); >+ state = (State) JavaModelManager.getJavaModelManager().getLastBuiltState(getJavaProject("P").getProject(), null); >+ assertFalse(state.sourceLocations[0].ignoreOptionalProblems); >+ } finally { >+ preferences.setAutoBuilding(autoBuild); >+ getWorkspace().setDescription(preferences); >+ deleteProject("P"); >+ } >+} > } >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests2.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests2.java >index a067924..8cf9c88 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests2.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests2.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -38,6 +38,7 @@ > import org.eclipse.jdt.core.IJavaProject; > import org.eclipse.jdt.core.IType; > import org.eclipse.jdt.core.JavaCore; >+import org.eclipse.jdt.core.JavaModelException; > import org.eclipse.jdt.core.tests.util.Util; > import org.eclipse.jdt.internal.codeassist.RelevanceConstants; > import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; >@@ -45,6 +46,10 @@ > import org.eclipse.jdt.internal.core.search.indexing.IndexManager; > > public class CompletionTests2 extends ModifyingResourceTests implements RelevanceConstants { >+ >+ static { >+// TESTS_NAMES = new String[]{"testBug340945"}; >+ } > > public static class CompletionContainerInitializer implements ContainerInitializer.ITestInitializer { > >@@ -5591,4 +5596,260 @@ > deleteProject(project); > } > } >+ >+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=292087 >+public void testBug340945() throws JavaModelException { >+ this.workingCopies = new ICompilationUnit[1]; >+ this.workingCopies[0] = getWorkingCopy( >+ "/Completion/src/test/Try.java", >+ "package test;\n" + >+ "public class Try extends Thread{\n" + >+ " int inty = 1;\n" + >+ " void foo() {\n" + >+ " int i = 1;\n" + >+ " Object o = new Object() {\n" + >+ " void running() {\n" + >+ " int j = 1;\n" + >+ " int k = " + >+ " }\n" + >+ " }\n" + >+ " }\n" + >+ "}\n"); >+ >+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); >+ requestor.setRequireExtendedContext(true); >+ requestor.allowAllRequiredProposals(); >+ requestor.setComputeVisibleElements(true); >+// requestor.setAssignableType("I"); >+ String str = this.workingCopies[0].getSource(); >+ String completeBehind = "int k ="; >+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length(); >+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); >+ assertResults( >+ "<CompleteOnName:>", >+ requestor.getCompletionNode()); >+ assertResults( >+ "int k = <CompleteOnName:>;", >+ requestor.getCompletionNodeParent()); >+ assertResults( >+ "int j[pos: unused][id:2]\n" + >+ "int i[pos: unused][id:0]\n" + >+ "java.lang.Object o[pos: unused][id:1]\n", >+ requestor.getVisibleLocalVariables()); >+ assertResults( >+ "int inty\n", >+ requestor.getVisibleFields()); >+ assertResults( >+ "void running() \n" + >+ "public final void wait(long, int) throws java.lang.IllegalMonitorStateException, java.lang.InterruptedException\n" + >+ "public final void wait(long) throws java.lang.IllegalMonitorStateException, java.lang.InterruptedException\n" + >+ "public final void wait() throws java.lang.IllegalMonitorStateException, java.lang.InterruptedException\n" + >+ "public java.lang.String toString() \n" + >+ "public final void notifyAll() throws java.lang.IllegalMonitorStateException\n" + >+ "public final void notify() throws java.lang.IllegalMonitorStateException\n" + >+ "public int hashCode() \n" + >+ "public final java.lang.Class getClass() \n" + >+ "protected void finalize() throws java.lang.Throwable\n" + >+ "public boolean equals(java.lang.Object) \n" + >+ "protected java.lang.Object clone() throws java.lang.CloneNotSupportedException\n" + >+ "void foo() \n", >+ requestor.getVisibleMethods()); >+} >+ >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=292087 >+public void testBug340945a() throws JavaModelException { >+ this.workingCopies = new ICompilationUnit[1]; >+ this.workingCopies[0] = getWorkingCopy( >+ "/Completion/src/test/Try.java", >+ "package test;\n" + >+ "public class Try extends Thread{\n" + >+ " int int1 = 1;\n" + >+ " int int2 = 2;\n" + >+ " int int3 = " + >+ "}\n"); >+ >+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); >+ requestor.setRequireExtendedContext(true); >+ requestor.allowAllRequiredProposals(); >+ requestor.setComputeVisibleElements(true); >+ String str = this.workingCopies[0].getSource(); >+ String completeBehind = "int int3 ="; >+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length(); >+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); >+ assertResults( >+ "<CompleteOnName:>", >+ requestor.getCompletionNode()); >+ assertResults( >+ "int int3 = <CompleteOnName:>;", >+ requestor.getCompletionNodeParent()); >+ assertResults( >+ "", >+ requestor.getVisibleLocalVariables()); >+ assertResults( >+ "int int2\n" + >+ "int int1\n", >+ requestor.getVisibleFields()); >+ assertResults( >+ "public final void wait(long, int) throws java.lang.IllegalMonitorStateException, java.lang.InterruptedException\n" + >+ "public final void wait(long) throws java.lang.IllegalMonitorStateException, java.lang.InterruptedException\n" + >+ "public final void wait() throws java.lang.IllegalMonitorStateException, java.lang.InterruptedException\n" + >+ "public java.lang.String toString() \n" + >+ "public final void notifyAll() throws java.lang.IllegalMonitorStateException\n" + >+ "public final void notify() throws java.lang.IllegalMonitorStateException\n" + >+ "public int hashCode() \n" + >+ "public final java.lang.Class getClass() \n" + >+ "protected void finalize() throws java.lang.Throwable\n" + >+ "public boolean equals(java.lang.Object) \n" + >+ "protected java.lang.Object clone() throws java.lang.CloneNotSupportedException\n", >+ requestor.getVisibleMethods()); >+} >+ >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=292087 >+public void testBug340945b() throws JavaModelException { >+ this.workingCopies = new ICompilationUnit[1]; >+ this.workingCopies[0] = getWorkingCopy( >+ "/Completion/src/test/Try.java", >+ "package test;\n" + >+ "public class Try extends Thread{\n" + >+ "Object field;\n" + >+ "void foo() {\n" + >+ " int int1 = 1;\n" + >+ " int int2 = 2;\n" + >+ " int int3 = " + >+ "}\n" + >+ "}\n"); >+ >+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); >+ requestor.setRequireExtendedContext(true); >+ requestor.allowAllRequiredProposals(); >+ requestor.setComputeVisibleElements(true); >+ String str = this.workingCopies[0].getSource(); >+ String completeBehind = "int int3 ="; >+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length(); >+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); >+ assertResults( >+ "<CompleteOnName:>", >+ requestor.getCompletionNode()); >+ assertResults( >+ "int int3 = <CompleteOnName:>;", >+ requestor.getCompletionNodeParent()); >+ assertResults( >+ "int int1[pos: unused][id:0]\n" + >+ "int int2[pos: unused][id:1]\n", >+ requestor.getVisibleLocalVariables()); >+ assertResults( >+ "java.lang.Object field\n", >+ requestor.getVisibleFields()); >+ assertResults( >+ "void foo() \n" + >+ "public final void wait(long, int) throws java.lang.IllegalMonitorStateException, java.lang.InterruptedException\n" + >+ "public final void wait(long) throws java.lang.IllegalMonitorStateException, java.lang.InterruptedException\n" + >+ "public final void wait() throws java.lang.IllegalMonitorStateException, java.lang.InterruptedException\n" + >+ "public java.lang.String toString() \n" + >+ "public final void notifyAll() throws java.lang.IllegalMonitorStateException\n" + >+ "public final void notify() throws java.lang.IllegalMonitorStateException\n" + >+ "public int hashCode() \n" + >+ "public final java.lang.Class getClass() \n" + >+ "protected void finalize() throws java.lang.Throwable\n" + >+ "public boolean equals(java.lang.Object) \n" + >+ "protected java.lang.Object clone() throws java.lang.CloneNotSupportedException\n", >+ requestor.getVisibleMethods()); >+} >+ >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=292087 >+public void testBug340945c() throws JavaModelException { >+ this.workingCopies = new ICompilationUnit[1]; >+ this.workingCopies[0] = getWorkingCopy( >+ "/Completion/src/test/Try.java", >+ "package test;\n" + >+ "public class Try extends Thread{\n" + >+ "Object field;\n" + >+ "void foo() {\n" + >+ " int int1 = 1;\n" + >+ " int int2 = 2;\n" + >+ " Object o1 = new Object();\n" + >+ " o1." + >+ "}\n" + >+ "}\n"); >+ >+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); >+ requestor.setRequireExtendedContext(true); >+ requestor.allowAllRequiredProposals(); >+ requestor.setComputeVisibleElements(true); >+ String str = this.workingCopies[0].getSource(); >+ String completeBehind = "o1."; >+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length(); >+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); >+ assertResults( >+ "<CompleteOnName:o1.>", >+ requestor.getCompletionNode()); >+ assertNull( >+ "should be null", >+ requestor.getCompletionNodeParent()); >+ assertResults( >+ "int int1[pos: unused][id:0]\n" + >+ "int int2[pos: unused][id:1]\n" + >+ "java.lang.Object o1[pos: unused][id:2]\n", >+ requestor.getVisibleLocalVariables()); >+ assertResults( >+ "java.lang.Object field\n", >+ requestor.getVisibleFields()); >+ assertResults( >+ "void foo() \n" + >+ "public final void wait(long, int) throws java.lang.IllegalMonitorStateException, java.lang.InterruptedException\n" + >+ "public final void wait(long) throws java.lang.IllegalMonitorStateException, java.lang.InterruptedException\n" + >+ "public final void wait() throws java.lang.IllegalMonitorStateException, java.lang.InterruptedException\n" + >+ "public java.lang.String toString() \n" + >+ "public final void notifyAll() throws java.lang.IllegalMonitorStateException\n" + >+ "public final void notify() throws java.lang.IllegalMonitorStateException\n" + >+ "public int hashCode() \n" + >+ "public final java.lang.Class getClass() \n" + >+ "protected void finalize() throws java.lang.Throwable\n" + >+ "public boolean equals(java.lang.Object) \n" + >+ "protected java.lang.Object clone() throws java.lang.CloneNotSupportedException\n", >+ requestor.getVisibleMethods()); >+} >+ >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=292087 >+public void testBug340945d() throws JavaModelException { >+ this.workingCopies = new ICompilationUnit[1]; >+ this.workingCopies[0] = getWorkingCopy( >+ "/Completion/src/test/Try.java", >+ "package test;\n" + >+ "public class Try extends Thread{\n" + >+ "Object field;\n" + >+ "static void foo() {\n" + // field should not be visible here >+ " int int1 = 1;\n" + >+ " int int2 = 2;\n" + >+ " Object o1 = new Object();\n" + >+ " o1." + >+ "}\n" + >+ "}\n"); >+ >+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); >+ requestor.setRequireExtendedContext(true); >+ requestor.allowAllRequiredProposals(); >+ requestor.setComputeVisibleElements(true); >+ String str = this.workingCopies[0].getSource(); >+ String completeBehind = "o1."; >+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length(); >+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); >+ assertResults( >+ "<CompleteOnName:o1.>", >+ requestor.getCompletionNode()); >+ assertNull( >+ "should be null", >+ requestor.getCompletionNodeParent()); >+ assertResults( >+ "int int1[pos: unused][id:0]\n" + >+ "int int2[pos: unused][id:1]\n" + >+ "java.lang.Object o1[pos: unused][id:2]\n", >+ requestor.getVisibleLocalVariables()); >+ assertResults( >+ "", >+ requestor.getVisibleFields()); >+ assertResults( >+ "static void foo() \n", >+ requestor.getVisibleMethods()); >+} > } >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTestsRequestor2.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTestsRequestor2.java >index c3102c4..09935f5 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTestsRequestor2.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTestsRequestor2.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2004, 2011 IBM Corporation and others. >+ * Copyright (c) 2004, 2012 IBM Corporation 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 >@@ -20,6 +20,9 @@ > import org.eclipse.jdt.core.IJavaElement; > import org.eclipse.jdt.core.Signature; > import org.eclipse.jdt.core.compiler.IProblem; >+import org.eclipse.jdt.internal.codeassist.InternalCompletionContext; >+import org.eclipse.jdt.internal.compiler.ast.ASTNode; >+import org.eclipse.jdt.internal.compiler.util.ObjectVector; > import org.eclipse.jdt.internal.core.JavaElement; > > public class CompletionTestsRequestor2 extends CompletionRequestor { >@@ -600,9 +603,58 @@ > > public boolean canUseDiamond(int proposalNo) { > if (proposalNo < this.proposals.length && this.proposals[proposalNo] != null) { >- System.out.println(this.proposals[proposalNo]); > return this.proposals[proposalNo].canUseDiamond(this.context); > } > return false; > } >+ >+ public String getCompletionNode() { >+ if (this.context instanceof InternalCompletionContext) { >+ InternalCompletionContext internalCompletionContext = (InternalCompletionContext) this.context; >+ ASTNode astNode = internalCompletionContext.getCompletionNode(); >+ if (astNode != null) return astNode.toString(); >+ >+ } >+ return null; >+ } >+ >+ public String getCompletionNodeParent() { >+ if (this.context instanceof InternalCompletionContext) { >+ InternalCompletionContext internalCompletionContext = (InternalCompletionContext) this.context; >+ ASTNode astNode = internalCompletionContext.getCompletionNodeParent(); >+ if (astNode != null) return astNode.toString(); >+ >+ } >+ return null; >+ } >+ >+ public String getVisibleLocalVariables() { >+ if (this.context instanceof InternalCompletionContext) { >+ InternalCompletionContext internalCompletionContext = (InternalCompletionContext) this.context; >+ ObjectVector locals = internalCompletionContext.getVisibleLocalVariables(); >+ if (locals != null) return locals.toString(); >+ >+ } >+ return null; >+ } >+ >+ public String getVisibleFields() { >+ if (this.context instanceof InternalCompletionContext) { >+ InternalCompletionContext internalCompletionContext = (InternalCompletionContext) this.context; >+ ObjectVector fields = internalCompletionContext.getVisibleFields(); >+ if (fields != null) return fields.toString(); >+ >+ } >+ return null; >+ } >+ >+ public String getVisibleMethods() { >+ if (this.context instanceof InternalCompletionContext) { >+ InternalCompletionContext internalCompletionContext = (InternalCompletionContext) this.context; >+ ObjectVector methods = internalCompletionContext.getVisibleMethods(); >+ if (methods != null) return methods.toString(); >+ >+ } >+ return null; >+ } > } >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests_1_5.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests_1_5.java >index 4cc9390..6521614 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests_1_5.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests_1_5.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -14286,4 +14286,24 @@ > "X1<T>[TYPE_REF]{, test, Ltest.X1<TT;>;, null, null, replace[77, 77], token[77, 77], " + relevance + "}", > requestor.getResults()); > } >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=361963 >+public void test361963() throws JavaModelException { >+ this.workingCopies = new ICompilationUnit[1]; >+ this.workingCopies[0] = getWorkingCopy( >+ "/Completion/src/X.java", >+ "public class X<T> {\n" + >+ " void g() {\n" + >+ " return new X() {\n" + >+ " void g() {\n" + >+ " Object o = new X<\n"); >+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, false, true, true, true, true); >+ requestor.allowAllRequiredProposals(); >+ String str = this.workingCopies[0].getSource(); >+ String completeBehind = "new X<"; >+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length(); >+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); >+ assertResults( >+ "X<T>[TYPE_REF]{, , LX<TT;>;, null, null, replace[116, 116], token[116, 116], 51}", >+ requestor.getResults()); >+} > } >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveElementsTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveElementsTests.java >index eec97ac..8ecb0b9 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveElementsTests.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveElementsTests.java >@@ -2452,7 +2452,7 @@ > try { > TestProgressMonitor monitor = TestProgressMonitor.getInstance(); > monitor.setCancelledCounter(1); >- movePositive(typeSource.getMethods(), new IJavaElement[] {typeDest}, null, null, false, monitor); >+ movePositive(typeSource.getMethods(), new IJavaElement[] {typeDest}, null, null, false, true, monitor); > } catch (OperationCanceledException e) { > isCanceled = true; > } >@@ -2488,7 +2488,7 @@ > try { > TestProgressMonitor monitor = TestProgressMonitor.getInstance(); > monitor.setCancelledCounter(1); >- movePositive(typeSource.getMethods(), new IJavaElement[] {typeDest}, null, null, false, monitor); >+ movePositive(typeSource.getMethods(), new IJavaElement[] {typeDest}, null, null, false, true, monitor); > } catch (OperationCanceledException e) { > isCanceled = true; > } >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveResourcesTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveResourcesTests.java >index 3d4d1ec..2b68fd0 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveResourcesTests.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveResourcesTests.java >@@ -80,7 +80,13 @@ > } > IJavaElementDelta destDelta = this.deltaListener.getDeltaFor(container, true); > assertTrue("Destination container not changed", destDelta != null && destDelta.getKind() == IJavaElementDelta.CHANGED); >- IJavaElementDelta[] deltas = destDelta.getAddedChildren(); >+ IJavaElementDelta[] deltas = null; >+ if (force) { >+ deltas = destDelta.getChangedChildren(); >+ } >+ else { >+ deltas = destDelta.getAddedChildren(); >+ } > // FIXME: not strong enough > boolean found = false; > for (int i = 0; i < deltas.length; i++) { >@@ -809,25 +815,38 @@ > * existing CU. > */ > public void testMoveCU03() throws CoreException { >- this.createFolder("/P/src/p1"); >- this.createFile( >- "/P/src/p1/X.java", >- "package p1;\n" + >- "public class X {\n" + >- "}" >- ); >- ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java"); >+ try { >+ this.createFolder("/P/src/p1"); >+ this.createFile( >+ "/P/src/p1/X.java", >+ "package p1;\n" + >+ "public class X {\n" + >+ "}" >+ ); >+ ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java"); > >- this.createFolder("/P/src/p2"); >- this.createFile( >- "/P/src/p2/X.java", >- "package p2;\n" + >- "public class X {\n" + >- "}" >- ); >- IPackageFragment pkgDest = getPackage("/P/src/p2"); >- >- movePositive(cuSource, pkgDest, null, null, true); >+ this.createFolder("/P/src/p2"); >+ this.createFile( >+ "/P/src/p2/X.java", >+ "package p2;\n" + >+ "public class X {\n" + >+ "}" >+ ); >+ IPackageFragment pkgDest = getPackage("/P/src/p2"); >+ startDeltas(); >+ movePositive(new IJavaElement[] {cuSource}, new IJavaElement[] {pkgDest}, null, null, true, false, null); >+ assertDeltas( >+ "Incorrect delta", >+ "P[*]: {CHILDREN}\n" >+ + " src[*]: {CHILDREN}\n" >+ + " p1[*]: {CHILDREN}\n" >+ + " X.java[-]: {MOVED_TO(X.java [in p2 [in src [in P]]])}\n" >+ + " p2[*]: {CHILDREN}\n" >+ + " X.java[*]: {CONTENT | PRIMARY RESOURCE}"); >+ } >+ finally { >+ stopDeltas(); >+ } > } > /** > * Ensures that a CU can be moved to a different package, >@@ -853,25 +872,39 @@ > * be renamed, overwriting an existing resource. > */ > public void testMoveCU05() throws CoreException { >- this.createFolder("/P/src/p1"); >- this.createFile( >- "/P/src/p1/X.java", >- "package p1;\n" + >- "public class X {\n" + >- "}" >- ); >- ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java"); >+ try { >+ this.createFolder("/P/src/p1"); >+ this.createFile( >+ "/P/src/p1/X.java", >+ "package p1;\n" + >+ "public class X {\n" + >+ "}" >+ ); >+ ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java"); > >- this.createFolder("/P/src/p2"); >- this.createFile( >- "/P/src/p2/Y.java", >- "package p2;\n" + >- "public class Y {\n" + >- "}" >- ); >- IPackageFragment pkgDest = getPackage("/P/src/p2"); >- >- movePositive(cuSource, pkgDest, null, "Y.java", true); >+ this.createFolder("/P/src/p2"); >+ this.createFile( >+ "/P/src/p2/Y.java", >+ "package p2;\n" + >+ "public class Y {\n" + >+ "}" >+ ); >+ IPackageFragment pkgDest = getPackage("/P/src/p2"); >+ startDeltas(); >+ movePositive(new IJavaElement[] {cuSource}, new IJavaElement[] {pkgDest}, null, new String[]{"Y.java"}, true, false, null); >+ assertDeltas( >+ "Incorrect delta", >+ "P[*]: {CHILDREN}\n" >+ + " src[*]: {CHILDREN}\n" >+ + " p1[*]: {CHILDREN}\n" >+ + " X.java[-]: {MOVED_TO(Y.java [in p2 [in src [in P]]])}\n" >+ + " p2[*]: {CHILDREN}\n" >+ + " Y.java[*]: {CHILDREN | FINE GRAINED | PRIMARY RESOURCE}\n" >+ + " Y[+]: {MOVED_FROM(X [in X.java [in p1 [in src [in P]]]])}"); >+ } >+ finally { >+ stopDeltas(); >+ } > } > /** > * Ensures that a CU cannot be moved to a different package, replacing an >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveTests.java >index b1066ae..c03e393 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveTests.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveTests.java >@@ -253,12 +253,15 @@ > public void movePositive(IJavaElement[] elements, IJavaElement[] destinations, IJavaElement[] siblings, String[] names, boolean force) throws JavaModelException { > movePositive(elements, destinations, siblings, names, force, null); > } >+public void movePositive(IJavaElement[] elements, IJavaElement[] destinations, IJavaElement[] siblings, String[] names, boolean force, IProgressMonitor monitor) throws JavaModelException { >+ movePositive(elements, destinations, siblings, names, force, true, null); >+} > /** > * Moves the elements to the containers with optional renaming > * and forcing. The operation should succeed, so any exceptions > * encountered are thrown. > */ >-public void movePositive(IJavaElement[] elements, IJavaElement[] destinations, IJavaElement[] siblings, String[] names, boolean force, IProgressMonitor monitor) throws JavaModelException { >+public void movePositive(IJavaElement[] elements, IJavaElement[] destinations, IJavaElement[] siblings, String[] names, boolean force, boolean checkDelta, IProgressMonitor monitor) throws JavaModelException { > // if forcing, ensure that a name collision exists > int i; > if (force) { >@@ -275,7 +278,7 @@ > } > > try { >- startDeltas(); >+ if(checkDelta) startDeltas(); > > // move > getJavaModel().move(elements, destinations, siblings, names, force, monitor); >@@ -341,24 +344,26 @@ > } > } > } >- IJavaElementDelta destDelta = null; >- if (isMainType(element, destinations[i]) && names != null && names[i] != null) { //moved/renamed main type to same cu >- destDelta = this.deltaListener.getDeltaFor(moved.getParent()); >- assertTrue("Renamed compilation unit as result of main type not added", destDelta != null && destDelta.getKind() == IJavaElementDelta.ADDED); >- assertTrue("flag should be F_MOVED_FROM", (destDelta.getFlags() & IJavaElementDelta.F_MOVED_FROM) > 0); >- assertTrue("moved from handle should be original", destDelta.getMovedFromElement().equals(element.getParent())); >- } else { >- destDelta = this.deltaListener.getDeltaFor(destinations[i], true); >- assertTrue("Destination container not changed", destDelta != null && destDelta.getKind() == IJavaElementDelta.CHANGED); >- IJavaElementDelta[] deltas = destDelta.getAddedChildren(); >- assertTrue("Added children not correct for element copy", deltas[i].getElement().equals(moved)); >- assertTrue("should be K_ADDED", deltas[i].getKind() == IJavaElementDelta.ADDED); >- IJavaElementDelta sourceDelta= this.deltaListener.getDeltaFor(element, false); >- assertTrue("should be K_REMOVED", sourceDelta.getKind() == IJavaElementDelta.REMOVED); >+ if(checkDelta) { >+ IJavaElementDelta destDelta = null; >+ if (isMainType(element, destinations[i]) && names != null && names[i] != null) { //moved/renamed main type to same cu >+ destDelta = this.deltaListener.getDeltaFor(moved.getParent()); >+ assertTrue("Renamed compilation unit as result of main type not added", destDelta != null && destDelta.getKind() == IJavaElementDelta.ADDED); >+ assertTrue("flag should be F_MOVED_FROM", (destDelta.getFlags() & IJavaElementDelta.F_MOVED_FROM) > 0); >+ assertTrue("moved from handle should be original", destDelta.getMovedFromElement().equals(element.getParent())); >+ } else { >+ destDelta = this.deltaListener.getDeltaFor(destinations[i], true); >+ assertTrue("Destination container not changed", destDelta != null && destDelta.getKind() == IJavaElementDelta.CHANGED); >+ IJavaElementDelta[] deltas = destDelta.getAddedChildren(); >+ assertTrue("Added children not correct for element copy", deltas[i].getElement().equals(moved)); >+ assertTrue("should be K_ADDED", deltas[i].getKind() == IJavaElementDelta.ADDED); >+ IJavaElementDelta sourceDelta= this.deltaListener.getDeltaFor(element, false); >+ assertTrue("should be K_REMOVED", sourceDelta.getKind() == IJavaElementDelta.REMOVED); >+ } > } > } > } finally { >- stopDeltas(); >+ if(checkDelta) stopDeltas(); > } > } > } >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/EncodingTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/EncodingTests.java >index c9368c8..8baa96a 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/EncodingTests.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/EncodingTests.java >@@ -28,6 +28,7 @@ > import org.eclipse.core.runtime.content.IContentDescription; > import org.eclipse.core.runtime.preferences.IEclipsePreferences; > import org.eclipse.core.runtime.preferences.InstanceScope; >+import org.eclipse.jdt.core.IClasspathAttribute; > import org.eclipse.jdt.core.IClasspathEntry; > import org.eclipse.jdt.core.ICompilationUnit; > import org.eclipse.jdt.core.IJavaProject; >@@ -62,7 +63,7 @@ > // Use this static initializer to specify subset for tests > // All specified tests which do not belong to the class are skipped... > static { >-// TESTS_NAMES = new String[] { "testBug110576" }; >+// TESTS_NAMES = new String[] { "testBug361356" }; > // TESTS_NUMBERS = new int[] { 2, 12 }; > // TESTS_RANGE = new int[] { 16, -1 }; > } >@@ -1217,7 +1218,256 @@ > getWorkspaceRoot().setDefaultCharset(wkspEncoding, null); > } > } >- >+ public void testBug361356() throws Exception { >+ String oldEncoding = this.encodingProject.getDefaultCharset(); >+ try{ >+ String encoding = "Shift-JIS"; >+ if (wkspEncoding.equals(encoding)) >+ getWorkspaceRoot().setDefaultCharset("UTF-8", null); >+ this.encodingProject.setDefaultCharset("UTF-8", null); >+ IJavaProject project = this.createJavaProject("Encoding2", new String[] {""}, ""); >+ IFile zipFile = (IFile) this.encodingProject.findMember("testShiftJIS.zip"); //$NON-NLS-1$ >+ IFile sourceFile = (IFile) this.encodingProject.findMember("src/testShiftJIS/A.java"); >+ >+ IClasspathEntry[] entries = this.encodingJavaProject.getRawClasspath(); >+ IClasspathEntry newEntry = null; >+ for (int index = 0; index < entries.length; index++) { >+ IClasspathEntry entry = entries[index]; >+ if (entry.getPath().toOSString().endsWith("testShiftJIS.jar")) { >+ newEntry = entries[index]; >+ } >+ } >+ >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, encoding); >+ project.setRawClasspath(new IClasspathEntry[]{JavaCore.newLibraryEntry(newEntry.getPath(), new Path("/Encoding/src"), null, null, new IClasspathAttribute[]{attribute}, false)}, null); >+ sourceFile.setCharset(null, null); >+ >+ IPackageFragmentRoot root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar"); >+ ISourceReference sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class"); >+ assertNotNull(sourceRef); >+ String source = sourceRef.getSource(); >+ assertNotNull(source); >+ String encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding)); >+ char[] charArray = encodedContents.toCharArray(); >+ encodedContents = new String(CharOperation.remove(charArray, '\r')); >+ charArray = source.toCharArray(); >+ source = new String(CharOperation.remove(charArray, '\r')); >+ assertTrue("Sources should be decoded the same way", encodedContents.equals(source)); >+ >+ attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, "UTF-8"); >+ project.setRawClasspath(new IClasspathEntry[]{JavaCore.newLibraryEntry(newEntry.getPath(), new Path("/Encoding/src"), null, null, new IClasspathAttribute[]{attribute}, false)}, null); >+ sourceFile.setCharset(encoding, null); >+ >+ root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar"); >+ sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class"); >+ assertNotNull(sourceRef); >+ source = sourceRef.getSource(); >+ assertNotNull(source); >+ encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding)); >+ charArray = encodedContents.toCharArray(); >+ encodedContents = new String(CharOperation.remove(charArray, '\r')); >+ charArray = source.toCharArray(); >+ source = new String(CharOperation.remove(charArray, '\r')); >+ assertTrue("Sources should be decoded the same way", encodedContents.equals(source)); >+ >+ attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, encoding); >+ project.setRawClasspath(new IClasspathEntry[]{JavaCore.newLibraryEntry(newEntry.getPath(), new Path("/Encoding/testShiftJIS.zip"), null, null, new IClasspathAttribute[]{attribute}, false)}, null); >+ zipFile.setCharset(null, null); >+ >+ root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar"); >+ sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class"); >+ assertNotNull(sourceRef); >+ source = sourceRef.getSource(); >+ assertNotNull(source); >+ encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding)); >+ charArray = encodedContents.toCharArray(); >+ encodedContents = new String(CharOperation.remove(charArray, '\r')); >+ charArray = source.toCharArray(); >+ source = new String(CharOperation.remove(charArray, '\r')); >+ assertTrue("Sources should be decoded the same way", encodedContents.equals(source)); >+ >+ attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, "UTF-8"); >+ project.setRawClasspath(new IClasspathEntry[]{JavaCore.newLibraryEntry(newEntry.getPath(), new Path("/Encoding/testShiftJIS.zip"), null, null, new IClasspathAttribute[]{attribute}, false)}, null); >+ zipFile.setCharset(encoding, null); >+ >+ root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar"); >+ sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class"); >+ assertNotNull(sourceRef); >+ source = sourceRef.getSource(); >+ assertNotNull(source); >+ encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding)); >+ charArray = encodedContents.toCharArray(); >+ encodedContents = new String(CharOperation.remove(charArray, '\r')); >+ charArray = source.toCharArray(); >+ source = new String(CharOperation.remove(charArray, '\r')); >+ assertTrue("Sources should be decoded the same way", encodedContents.equals(source)); >+ >+ } >+ finally { >+ this.encodingProject.setDefaultCharset(oldEncoding, null); >+ deleteProject("Encoding2"); >+ getWorkspaceRoot().setDefaultCharset(wkspEncoding, null); >+ } >+ } >+ public void testBug361356a() throws Exception { >+ String oldEncoding = this.encodingProject.getDefaultCharset(); >+ try{ >+ String encoding = "Shift-JIS"; >+ if (wkspEncoding.equals(encoding)) >+ getWorkspaceRoot().setDefaultCharset("UTF-8", null); >+ this.encodingProject.setDefaultCharset("UTF-8", null); >+ IJavaProject project = this.createJavaProject("Encoding2", new String[] {""}, ""); >+ IFile zipFile = (IFile) this.encodingProject.findMember("testShiftJIS.zip"); //$NON-NLS-1$ >+ IFile sourceFile = (IFile) this.encodingProject.findMember("src/testShiftJIS/A.java"); >+ >+ IClasspathEntry[] entries = this.encodingJavaProject.getRawClasspath(); >+ IClasspathEntry newEntry = null; >+ for (int index = 0; index < entries.length; index++) { >+ IClasspathEntry entry = entries[index]; >+ if (entry.getPath().toOSString().endsWith("testShiftJIS.jar")) { >+ newEntry = entries[index]; >+ } >+ } >+ >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, encoding); >+ attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, encoding); >+ project.setRawClasspath(new IClasspathEntry[]{JavaCore.newLibraryEntry(newEntry.getPath(), new Path("/Encoding/testShiftJIS.zip"), null, null, new IClasspathAttribute[]{attribute}, false)}, null); >+ zipFile.setCharset(null, null); >+ >+ IPackageFragmentRoot root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar"); >+ ISourceReference sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class"); >+ assertNotNull(sourceRef); >+ String source = sourceRef.getSource(); >+ assertNotNull(source); >+ String encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding)); >+ char[] charArray = encodedContents.toCharArray(); >+ encodedContents = new String(CharOperation.remove(charArray, '\r')); >+ charArray = source.toCharArray(); >+ source = new String(CharOperation.remove(charArray, '\r')); >+ assertTrue("Sources should be decoded the same way", encodedContents.equals(source)); >+ >+ attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, "UTF-8"); >+ project.setRawClasspath(new IClasspathEntry[]{JavaCore.newLibraryEntry(newEntry.getPath(), new Path("/Encoding/testShiftJIS.zip"), null, null, new IClasspathAttribute[]{attribute}, false)}, null); >+ zipFile.setCharset(encoding, null); >+ >+ root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar"); >+ sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class"); >+ assertNotNull(sourceRef); >+ source = sourceRef.getSource(); >+ assertNotNull(source); >+ encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding)); >+ charArray = encodedContents.toCharArray(); >+ encodedContents = new String(CharOperation.remove(charArray, '\r')); >+ charArray = source.toCharArray(); >+ source = new String(CharOperation.remove(charArray, '\r')); >+ assertTrue("Sources should be decoded the same way", encodedContents.equals(source)); >+ } >+ finally { >+ this.encodingProject.setDefaultCharset(oldEncoding, null); >+ deleteProject("Encoding2"); >+ getWorkspaceRoot().setDefaultCharset(wkspEncoding, null); >+ } >+ } >+ public void testBug361356b() throws Exception { >+ String oldEncoding = this.encodingProject.getDefaultCharset(); >+ File externalSourceZip = null; >+ File externalSource = null; >+ try{ >+ String encoding = "Shift-JIS"; >+ if (wkspEncoding.equals(encoding)) >+ getWorkspaceRoot().setDefaultCharset("UTF-8", null); >+ this.encodingProject.setDefaultCharset("UTF-8", null); >+ IJavaProject project = this.createJavaProject("Encoding2", new String[] {""}, ""); >+ IFile sourceFile = (IFile) this.encodingProject.findMember("src/testShiftJIS/A.java"); >+ >+ File internalSourceZip = new File(getWorkspacePath(), "/Encoding/testShiftJIS.zip"); >+ externalSourceZip = new File(getExternalPath(), "testShiftJIS.zip"); >+ File internalSource = new File(getWorkspacePath(), "/Encoding/src"); >+ externalSource = new File(getExternalPath(), "testShiftJIS"); >+ >+ copyDirectory(internalSource, externalSource); >+ copy(internalSourceZip, externalSourceZip); >+ >+ IClasspathEntry[] entries = this.encodingJavaProject.getRawClasspath(); >+ IClasspathEntry newEntry = null; >+ for (int index = 0; index < entries.length; index++) { >+ IClasspathEntry entry = entries[index]; >+ if (entry.getPath().toOSString().endsWith("testShiftJIS.jar")) { >+ newEntry = entries[index]; >+ } >+ } >+ >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, encoding); >+ attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, encoding); >+ project.setRawClasspath(new IClasspathEntry[]{JavaCore.newLibraryEntry(newEntry.getPath(), new Path(getExternalResourcePath("testShiftJIS.zip")), null, null, new IClasspathAttribute[]{attribute}, false)}, null); >+ >+ IPackageFragmentRoot root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar"); >+ ISourceReference sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class"); >+ assertNotNull(sourceRef); >+ String source = sourceRef.getSource(); >+ assertNotNull(source); >+ String encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding)); >+ char[] charArray = encodedContents.toCharArray(); >+ encodedContents = new String(CharOperation.remove(charArray, '\r')); >+ charArray = source.toCharArray(); >+ source = new String(CharOperation.remove(charArray, '\r')); >+ assertTrue("Sources should be decoded the same way", encodedContents.equals(source)); >+ >+ attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, "UTF-8"); >+ project.setRawClasspath(new IClasspathEntry[]{JavaCore.newLibraryEntry(newEntry.getPath(), new Path(getExternalResourcePath("testShiftJIS.zip")), null, null, new IClasspathAttribute[]{attribute}, false)}, null); >+ >+ root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar"); >+ sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class"); >+ assertNotNull(sourceRef); >+ source = sourceRef.getSource(); >+ assertNotNull(source); >+ encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding)); >+ charArray = encodedContents.toCharArray(); >+ encodedContents = new String(CharOperation.remove(charArray, '\r')); >+ charArray = source.toCharArray(); >+ source = new String(CharOperation.remove(charArray, '\r')); >+ assertFalse("Sources should not be decoded the same way", encodedContents.equals(source)); >+ >+ attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, encoding); >+ project.setRawClasspath(new IClasspathEntry[]{JavaCore.newLibraryEntry(newEntry.getPath(), new Path(getExternalResourcePath("testShiftJIS")), null, null, new IClasspathAttribute[]{attribute}, false)}, null); >+ sourceFile.setCharset(null, null); >+ >+ root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar"); >+ sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class"); >+ assertNotNull(sourceRef); >+ source = sourceRef.getSource(); >+ assertNotNull(source); >+ encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding)); >+ charArray = encodedContents.toCharArray(); >+ encodedContents = new String(CharOperation.remove(charArray, '\r')); >+ charArray = source.toCharArray(); >+ source = new String(CharOperation.remove(charArray, '\r')); >+ assertTrue("Sources should be decoded the same way", encodedContents.equals(source)); >+ >+ attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING, "UTF-8"); >+ project.setRawClasspath(new IClasspathEntry[]{JavaCore.newLibraryEntry(newEntry.getPath(), new Path(getExternalResourcePath("testShiftJIS")), null, null, new IClasspathAttribute[]{attribute}, false)}, null); >+ sourceFile.setCharset(encoding, null); >+ >+ root = getPackageFragmentRoot("Encoding2", "testShiftJIS.jar"); >+ sourceRef = root.getPackageFragment("testShiftJIS").getClassFile("A.class"); >+ assertNotNull(sourceRef); >+ source = sourceRef.getSource(); >+ assertNotNull(source); >+ encodedContents = new String (Util.getResourceContentsAsCharArray(sourceFile, encoding)); >+ charArray = encodedContents.toCharArray(); >+ encodedContents = new String(CharOperation.remove(charArray, '\r')); >+ charArray = source.toCharArray(); >+ source = new String(CharOperation.remove(charArray, '\r')); >+ assertFalse("Sources should not be decoded the same way", encodedContents.equals(source)); >+ } >+ finally { >+ if (externalSourceZip != null) externalSourceZip.delete(); >+ if (externalSource != null) deleteExternalResource("testShiftJIS"); >+ this.encodingProject.setDefaultCharset(oldEncoding, null); >+ deleteProject("Encoding2"); >+ getWorkspaceRoot().setDefaultCharset(wkspEncoding, null); >+ } >+ } > private void verifyUtf8BOM(IFile file) throws CoreException { > assertNull("File should not have any explicit charset", file.getCharset(false)); > IContentDescription contentDescription = file.getContentDescription(); >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/IgnoreOptionalProblemsFromSourceFoldersTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/IgnoreOptionalProblemsFromSourceFoldersTests.java >new file mode 100644 >index 0000000..87fb395 >--- /dev/null >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/IgnoreOptionalProblemsFromSourceFoldersTests.java >@@ -0,0 +1,289 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 IBM Corporation 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.core.tests.model; >+ >+import junit.framework.Test; >+ >+import org.eclipse.core.resources.IFile; >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.core.runtime.Path; >+import org.eclipse.jdt.core.IClasspathAttribute; >+import org.eclipse.jdt.core.IClasspathEntry; >+import org.eclipse.jdt.core.ICompilationUnit; >+import org.eclipse.jdt.core.IJavaProject; >+import org.eclipse.jdt.core.JavaCore; >+import org.eclipse.jdt.core.WorkingCopyOwner; >+ >+public class IgnoreOptionalProblemsFromSourceFoldersTests extends ModifyingResourceTests { >+ private static final IClasspathAttribute ATTR_IGNORE_OPTIONAL_PROBLEMS_TRUE = JavaCore.newClasspathAttribute(IClasspathAttribute.IGNORE_OPTIONAL_PROBLEMS, "true"); >+ >+ public static Test suite() { >+ return buildModelTestSuite(IgnoreOptionalProblemsFromSourceFoldersTests.class); >+ } >+ >+ public IgnoreOptionalProblemsFromSourceFoldersTests(String name) { >+ super(name); >+ } >+ >+ // ignore optional errors >+ public void test001() throws CoreException { >+ ICompilationUnit unit = null; >+ try { >+ IJavaProject project = createJavaProject("P", new String[] {}, new String[] { "JCL_LIB" }, "bin"); >+ project.setOption(JavaCore.COMPILER_PB_UNUSED_LOCAL, JavaCore.ERROR); >+ >+ IClasspathEntry[] originalCP = project.getRawClasspath(); >+ IClasspathEntry[] newCP = new IClasspathEntry[originalCP.length + 1]; >+ System.arraycopy(originalCP, 0, newCP, 0, originalCP.length); >+ newCP[originalCP.length] = JavaCore.newSourceEntry(new Path("/P/src"), null, null, null, >+ new IClasspathAttribute[] { ATTR_IGNORE_OPTIONAL_PROBLEMS_TRUE }); >+ project.setRawClasspath(newCP, null); >+ >+ createFolder("/P/src/p"); >+ IFile file = createFile("/P/src/p/X.java", >+ "package p;\n" + >+ "public class X {\n" + >+ " public void foo() {\n" + >+ " int i;\n" + >+ " }\n" + >+ "}"); >+ unit = (ICompilationUnit) JavaCore.create(file); >+ >+ ProblemRequestor problemRequestor = new ProblemRequestor(); >+ WorkingCopyOwner owner = newWorkingCopyOwner(problemRequestor); >+ unit.getWorkingCopy(owner, null); >+ assertProblems("Unexpected problems", >+ "----------\n" + >+ "----------\n", >+ problemRequestor); >+ } finally { >+ if (unit != null) { >+ unit.discardWorkingCopy(); >+ } >+ deleteProject("P"); >+ } >+ } >+ >+ // two different source folders ignore only from one >+ public void test002() throws CoreException { >+ ICompilationUnit x = null; >+ ICompilationUnit y = null; >+ try { >+ IJavaProject project = createJavaProject("P", new String[] {}, new String[] { "JCL_LIB" }, "bin"); >+ project.setOption(JavaCore.COMPILER_PB_UNUSED_LOCAL, JavaCore.ERROR); >+ >+ IClasspathEntry[] originalCP = project.getRawClasspath(); >+ IClasspathEntry[] newCP = new IClasspathEntry[originalCP.length + 2]; >+ System.arraycopy(originalCP, 0, newCP, 0, originalCP.length); >+ newCP[originalCP.length] = JavaCore.newSourceEntry(new Path("/P/src"), null, null, null, >+ new IClasspathAttribute[] { ATTR_IGNORE_OPTIONAL_PROBLEMS_TRUE }); >+ newCP[originalCP.length + 1] = JavaCore.newSourceEntry(new Path("/P/src2")); >+ project.setRawClasspath(newCP, null); >+ >+ createFolder("/P/src/p"); >+ IFile fileX = createFile("/P/src/p/X.java", >+ "package p;\n" + >+ "public class X {\n" + >+ " public void foo() {\n" + >+ " int i;\n" + >+ " }\n" + >+ "}"); >+ x = (ICompilationUnit) JavaCore.create(fileX); >+ createFolder("/P/src2/q"); >+ IFile fileY = createFile("/P/src2/q/Y.java", >+ "package q;\n" + >+ "public class Y {\n" + >+ " public void foo() {\n" + >+ " int i;\n" + >+ " }\n" + >+ "}"); >+ y = (ICompilationUnit) JavaCore.create(fileY); >+ >+ ProblemRequestor problemRequestorX = new ProblemRequestor(); >+ WorkingCopyOwner ownerX = newWorkingCopyOwner(problemRequestorX); >+ x.getWorkingCopy(ownerX, null); >+ assertProblems("Unexpected problems", >+ "----------\n" + >+ "----------\n", >+ problemRequestorX); >+ >+ ProblemRequestor problemRequestorY = new ProblemRequestor(); >+ WorkingCopyOwner ownerY = newWorkingCopyOwner(problemRequestorY); >+ y.getWorkingCopy(ownerY, null); >+ assertProblems("Unexpected problems value", >+ "----------\n" + >+ "1. ERROR in /P/src2/q/Y.java\n" + >+ "The value of the local variable i is not used\n" + >+ "----------\n", >+ problemRequestorY); >+ } finally { >+ if (x != null) { >+ x.discardWorkingCopy(); >+ } >+ if (y != null) { >+ y.discardWorkingCopy(); >+ } >+ deleteProject("P"); >+ } >+ } >+ >+ // two different source folders ignore from both >+ public void test003() throws CoreException { >+ ICompilationUnit x = null; >+ ICompilationUnit y = null; >+ try { >+ IJavaProject project = createJavaProject("P", new String[] {}, new String[] { "JCL_LIB" }, "bin"); >+ project.setOption(JavaCore.COMPILER_PB_UNUSED_LOCAL, JavaCore.ERROR); >+ >+ IClasspathEntry[] originalCP = project.getRawClasspath(); >+ IClasspathEntry[] newCP = new IClasspathEntry[originalCP.length + 2]; >+ System.arraycopy(originalCP, 0, newCP, 0, originalCP.length); >+ newCP[originalCP.length] = JavaCore.newSourceEntry(new Path("/P/src"), null, null, null, >+ new IClasspathAttribute[] { ATTR_IGNORE_OPTIONAL_PROBLEMS_TRUE }); >+ newCP[originalCP.length + 1] = JavaCore.newSourceEntry(new Path("/P/src2"), null, null, null, >+ new IClasspathAttribute[] { ATTR_IGNORE_OPTIONAL_PROBLEMS_TRUE }); >+ project.setRawClasspath(newCP, null); >+ >+ createFolder("/P/src/p"); >+ IFile fileX = createFile("/P/src/p/X.java", >+ "package p;\n" + >+ "public class X {\n" + >+ " public void foo() {\n" + >+ " int i;\n" + >+ " }\n" + >+ "}"); >+ x = (ICompilationUnit) JavaCore.create(fileX); >+ createFolder("/P/src2/q"); >+ IFile fileY = createFile("/P/src2/q/Y.java", >+ "package q;\n" + >+ "public class Y {\n" + >+ " public void foo() {\n" + >+ " int i;\n" + >+ " }\n" + >+ "}"); >+ y = (ICompilationUnit) JavaCore.create(fileY); >+ >+ ProblemRequestor problemRequestorX = new ProblemRequestor(); >+ WorkingCopyOwner ownerX = newWorkingCopyOwner(problemRequestorX); >+ x.getWorkingCopy(ownerX, null); >+ assertProblems("Unexpected problems", >+ "----------\n" + >+ "----------\n", >+ problemRequestorX); >+ >+ ProblemRequestor problemRequestorY = new ProblemRequestor(); >+ WorkingCopyOwner ownerY = newWorkingCopyOwner(problemRequestorY); >+ y.getWorkingCopy(ownerY, null); >+ assertProblems("Unexpected problems", >+ "----------\n" + >+ "----------\n", >+ problemRequestorY); >+ } finally { >+ if (x != null) { >+ x.discardWorkingCopy(); >+ } >+ if (y != null) { >+ y.discardWorkingCopy(); >+ } >+ deleteProject("P"); >+ } >+ } >+ >+ // non-optional errors cannot be ignored >+ public void test004() throws CoreException { >+ ICompilationUnit unit = null; >+ try { >+ IJavaProject project = createJavaProject("P", new String[] {}, new String[] { "JCL_LIB" }, "bin"); >+ project.setOption(JavaCore.COMPILER_PB_UNUSED_LOCAL, JavaCore.ERROR); >+ >+ IClasspathEntry[] originalCP = project.getRawClasspath(); >+ IClasspathEntry[] newCP = new IClasspathEntry[originalCP.length + 1]; >+ System.arraycopy(originalCP, 0, newCP, 0, originalCP.length); >+ newCP[originalCP.length] = JavaCore.newSourceEntry(new Path("/P/src"), null, null, null, >+ new IClasspathAttribute[] { ATTR_IGNORE_OPTIONAL_PROBLEMS_TRUE }); >+ project.setRawClasspath(newCP, null); >+ >+ createFolder("/P/src/p"); >+ IFile file = createFile("/P/src/p/X.java", >+ "package p;\n" + >+ "public class X {\n" + >+ " public void foo() {\n" + >+ " int i;\n" + >+ " }\n" + >+ " public void bar() {\n" + >+ " a++;\n" + >+ " }\n" + >+ "}"); >+ unit = (ICompilationUnit) JavaCore.create(file); >+ >+ ProblemRequestor problemRequestor = new ProblemRequestor(); >+ WorkingCopyOwner owner = newWorkingCopyOwner(problemRequestor); >+ unit.getWorkingCopy(owner, null); >+ assertProblems("Unexpeted problems", >+ "----------\n" + >+ "1. ERROR in /P/src/p/X.java\n" + >+ "a cannot be resolved to a variable\n" + >+ "----------\n", >+ problemRequestor); >+ } finally { >+ if (unit != null) { >+ unit.discardWorkingCopy(); >+ } >+ deleteProject("P"); >+ } >+ } >+ >+ // task tags cannot be ignored >+ public void test005() throws CoreException { >+ ICompilationUnit unit = null; >+ try { >+ IJavaProject project = createJavaProject("P", new String[] {}, new String[] { "JCL_LIB" }, "bin"); >+ project.setOption(JavaCore.COMPILER_PB_UNUSED_LOCAL, JavaCore.ERROR); >+ project.setOption(JavaCore.COMPILER_TASK_TAGS, "TODO"); >+ project.setOption(JavaCore.COMPILER_TASK_PRIORITIES, "NORMAL"); >+ >+ IClasspathEntry[] originalCP = project.getRawClasspath(); >+ IClasspathEntry[] newCP = new IClasspathEntry[originalCP.length + 1]; >+ System.arraycopy(originalCP, 0, newCP, 0, originalCP.length); >+ newCP[originalCP.length] = JavaCore.newSourceEntry(new Path("/P/src"), null, null, null, >+ new IClasspathAttribute[] { ATTR_IGNORE_OPTIONAL_PROBLEMS_TRUE }); >+ project.setRawClasspath(newCP, null); >+ >+ createFolder("/P/src/p"); >+ IFile file = createFile("/P/src/p/X.java", >+ "package p;\n" + >+ "public class X {\n" + >+ " public void foo() {\n" + >+ " int i;\n" + >+ " }\n" + >+ " public void bar() {\n" + >+ " // TODO nothing\n" + >+ " }\n" + >+ "}"); >+ unit = (ICompilationUnit) JavaCore.create(file); >+ >+ ProblemRequestor problemRequestor = new ProblemRequestor(); >+ WorkingCopyOwner owner = newWorkingCopyOwner(problemRequestor); >+ unit.getWorkingCopy(owner, null); >+ assertProblems("Unexpeted problems", >+ "----------\n" + >+ "1. WARNING in /P/src/p/X.java\n" + >+ "TODO nothing\n" + >+ "----------\n", >+ problemRequestor); >+ } finally { >+ if (unit != null) { >+ unit.discardWorkingCopy(); >+ } >+ deleteProject("P"); >+ } >+ } >+} >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaIndexTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaIndexTests.java >new file mode 100644 >index 0000000..1893d3f >--- /dev/null >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaIndexTests.java >@@ -0,0 +1,866 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 IBM Corporation 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.core.tests.model; >+ >+import java.io.File; >+import java.io.IOException; >+import java.net.URL; >+ >+import junit.framework.Test; >+ >+import org.eclipse.core.resources.IProject; >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.core.runtime.IPath; >+import org.eclipse.core.runtime.Path; >+import org.eclipse.core.runtime.preferences.IEclipsePreferences; >+import org.eclipse.core.runtime.preferences.InstanceScope; >+import org.eclipse.jdt.core.ClasspathContainerInitializer; >+import org.eclipse.jdt.core.IClasspathAttribute; >+import org.eclipse.jdt.core.IClasspathEntry; >+import org.eclipse.jdt.core.IJavaElement; >+import org.eclipse.jdt.core.IJavaProject; >+import org.eclipse.jdt.core.JavaCore; >+import org.eclipse.jdt.core.index.*; >+import org.eclipse.jdt.core.search.SearchEngine; >+import org.eclipse.jdt.core.tests.util.Util; >+import org.eclipse.jdt.internal.core.JavaModelManager; >+import org.eclipse.jdt.internal.core.UserLibraryClasspathContainer; >+import org.osgi.service.prefs.BackingStoreException; >+ >+public class JavaIndexTests extends AbstractJavaSearchTests { >+ >+ static { >+ // TESTS_NAMES = new String[] {"testPlatformIndexFile"}; >+ } >+ public JavaIndexTests(String name) { >+ super(name); >+ } >+ >+ public static Test suite() { >+ return buildModelTestSuite(JavaIndexTests.class); >+ } >+ // Test that the index file is really generated. >+ public void testGenerateIndex() throws IOException { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ >+ JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath); >+ assertTrue(new File(indexFilePath).exists()); >+ } finally { >+ new File(indexFilePath).delete(); >+ new File(jarFilePath).delete(); >+ } >+ } >+ >+ // Test that the index file and the jar can be deleted after the indexing is done >+ // This is to ensure that the files are closed >+ public void testDeleteIndexedFile() { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath); >+ assertTrue("Could not delete the index file", new File(indexFilePath).delete()); >+ assertTrue("Could not delete the jar file", new File(jarFilePath).delete()); >+ } catch (IOException e) { >+ assertFalse("Test failed", true); >+ } >+ } >+ >+ // Test that search works fine with the index file >+ public void testUseIndex() throws CoreException, IOException { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath); >+ long modified = new File(indexFilePath).lastModified(); >+ >+ IJavaProject p = createJavaProject("P"); >+ Path libPath = new Path(jarFilePath); >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, "file:///"+indexFilePath); >+ IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ >+ waitUntilIndexesReady(); >+ >+ // Test that specified index file is really used >+ java.io.File indexFile = JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexFile(); >+ assertEquals("Specified index file is not being used", indexFilePath,indexFile.toString()); >+ >+ // Test that search works properly >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ >+ // Ensure that the index file is not modified >+ assertEquals(modified, new File(indexFilePath).lastModified()); >+ } finally { >+ deleteProject("P"); >+ new File(indexFilePath).delete(); >+ new File(jarFilePath).delete(); >+ } >+ } >+ >+ // Test that the same index file is used even after restarting >+ public void testUseIndexAfterRestart() throws IOException, CoreException { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath); >+ long modified = new File(indexFilePath).lastModified(); >+ IJavaProject p = createJavaProject("P"); >+ Path libPath = new Path(jarFilePath); >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, "file:///"+indexFilePath); >+ IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ >+ simulateExitRestart(); >+ getJavaModel().refreshExternalArchives(null, null); >+ waitUntilIndexesReady(); >+ >+ this.resultCollector = new JavaSearchResultCollector(); >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ >+ java.io.File indexFile = JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexFile(); >+ assertEquals(indexFilePath,indexFile.toString()); >+ // Ensure that the file is not modified >+ assertEquals(modified, new File(indexFilePath).lastModified()); >+ } finally { >+ deleteProject("P"); >+ new File(indexFilePath).delete(); >+ new File(jarFilePath).delete(); >+ } >+ } >+ >+ // Test that the same index file is used even after restarting >+ public void testUseIndexInternalJarAfterRestart() throws IOException, CoreException { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = "/P/Test.jar"; >+ String fullJarPath = getWorkspacePath() + jarFilePath; >+ try { >+ IJavaProject p = createJavaProject("P"); >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, fullJarPath); >+ p.getProject().refreshLocal(1, null); >+ JavaIndexer.generateIndexForJar(fullJarPath, indexFilePath); >+ long modified = new File(indexFilePath).lastModified(); >+ IPath libPath = new Path(jarFilePath); >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, "file:///"+indexFilePath); >+ IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults("Test.jar pkg.Test [No source]"); >+ java.io.File indexFile = JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexFile(); >+ assertEquals(indexFilePath,indexFile.toString()); >+ >+ simulateExitRestart(); >+ waitUntilIndexesReady(); >+ >+ this.resultCollector = new JavaSearchResultCollector(); >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults("Test.jar pkg.Test [No source]"); >+ >+ indexFile = JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexFile(); >+ assertEquals(indexFilePath,indexFile.toString()); >+ // Ensure that the file is not modified >+ assertEquals(modified, new File(indexFilePath).lastModified()); >+ } finally { >+ deleteProject("P"); >+ new File(indexFilePath).delete(); >+ } >+ } >+ >+ // Test that a jar file that gets modified after the index is created doesn't return new changes. >+ // This behavior might have to be modified but.. >+ public void testModifyJarAfterIndex() throws CoreException, IOException { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath); >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}", >+ "pkg/NewTest.java", >+ "package pkg;\n" + >+ "public class NewTest {\n" + >+ " protected NewTest(int i) {}\n" + >+ "}"}, jarFilePath); >+ IJavaProject p = createJavaProject("P"); >+ Path libPath = new Path(jarFilePath); >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, "file:///"+indexFilePath); >+ IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ search("NewTest", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(""); >+ } finally { >+ deleteProject("P"); >+ new File(indexFilePath).delete(); >+ new File(jarFilePath).delete(); >+ } >+ } >+ >+ // test a non-existent index >+ public void testNonExistentIndex() throws CoreException, IOException { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ IJavaProject p = createJavaProject("P"); >+ Path libPath = new Path(jarFilePath); >+ new File(indexFilePath).delete(); >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, "file:///"+indexFilePath); >+ IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ >+ } finally { >+ deleteProject("P"); >+ new File(indexFilePath).delete(); >+ new File(jarFilePath).delete(); >+ } >+ } >+ >+ // test a non-existent index >+ public void testNonExistentIndexRestart() throws CoreException, IOException { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ >+ new File(indexFilePath).delete(); >+ >+ IJavaProject p = createJavaProject("P"); >+ Path libPath = new Path(jarFilePath); >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, "file:///"+indexFilePath); >+ IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ >+ java.io.File indexFile = JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexFile(); >+ long modified = indexFile.lastModified(); >+ assertEquals(modified, indexFile.lastModified()); >+ >+ simulateExitRestart(); >+ getJavaModel().refreshExternalArchives(null,null); >+ waitUntilIndexesReady(); >+ >+ this.resultCollector = new JavaSearchResultCollector(); >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ >+ indexFile = JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexFile(); >+ assertEquals("Index File should not have got modified",modified, indexFile.lastModified()); >+ } finally { >+ deleteProject("P"); >+ new File(indexFilePath).delete(); >+ new File(jarFilePath).delete(); >+ } >+ } >+ >+ // test that if the index is not existent after restart, it should build up a new index >+ public void testNonExistentIndexAfterRestart() throws CoreException, IOException { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ "protected Test(int i) {}\n" + "}" >+ },jarFilePath); >+ JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath); >+ >+ IJavaProject p = createJavaProject("P"); >+ Path libPath = new Path(jarFilePath); >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, "file:///"+indexFilePath); >+ IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ >+ simulateExitRestart(); >+ File indexFile = new File(indexFilePath); >+ indexFile.delete(); >+ assertTrue(!indexFile.exists()); >+ getJavaModel().refreshExternalArchives(null,null); >+ waitUntilIndexesReady(); >+ >+ this.resultCollector = new JavaSearchResultCollector(); >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ >+ } finally { >+ deleteProject("P"); >+ new File(indexFilePath).delete(); >+ new File(jarFilePath).delete(); >+ } >+ } >+ >+ // test a non-existent index which becomes existent after restart >+ public void testExistentIndexAfterRestart() throws CoreException, IOException { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ >+ File indexFile = new File(indexFilePath); >+ indexFile.delete(); >+ assertTrue(!indexFile.exists()); >+ >+ IJavaProject p = createJavaProject("P"); >+ Path libPath = new Path(jarFilePath); >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, "file:///"+indexFilePath); >+ IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ >+ JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath); >+ simulateExitRestart(); >+ getJavaModel().refreshExternalArchives(null,null); >+ waitUntilIndexesReady(); >+ >+ this.resultCollector = new JavaSearchResultCollector(); >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ >+ indexFile = JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexFile(); >+ assertEquals(indexFilePath,indexFile.toString()); >+ } finally { >+ deleteProject("P"); >+ new File(indexFilePath).delete(); >+ new File(jarFilePath).delete(); >+ } >+ } >+ >+ // Test that the index file is not deleted when the project is deleted >+ public void testDeleteProject() throws CoreException, IOException { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath); >+ IJavaProject p = createJavaProject("P"); >+ createExternalFolder("externalLib"); >+ Path libPath = new Path(jarFilePath); >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, "file:///"+indexFilePath); >+ IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ deleteProject("P"); >+ File f = new File(indexFilePath); >+ assertTrue(f.exists()); >+ } finally { >+ new File(indexFilePath).delete(); >+ new File(jarFilePath).delete(); >+ } >+ } >+ >+ >+ >+ // Test index file in platform >+ public void testPlatformIndexFile() throws CoreException, IOException { >+ String indexFilePath = null; >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ String indexUrl = "platform:/resource/P/Test.index"; >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ >+ IJavaProject p = createJavaProject("P"); >+ indexFilePath = p.getProject().getLocation().append("Test.index").toFile().getAbsolutePath(); >+ JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath); >+ long modified = new File(indexFilePath).lastModified(); >+ >+ Path libPath = new Path(jarFilePath); >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, indexUrl); >+ IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ >+ String indexFileName = JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexFile().getName(); >+ assertEquals(indexFileName, "Test.index"); >+ >+ simulateExitRestart(); >+ getJavaModel().refreshExternalArchives(null,null); >+ waitUntilIndexesReady(); >+ >+ this.resultCollector = new JavaSearchResultCollector(); >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ >+ indexFileName = JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexFile().getName(); >+ assertEquals(indexFileName, "Test.index"); >+ >+ assertEquals(modified, new File(indexFilePath).lastModified()); >+ } finally { >+ deleteProject("P"); >+ if (indexFilePath != null) new File(indexFilePath).delete(); >+ new File(jarFilePath).delete(); >+ } >+ } >+ >+ >+ public void testEditClasspath() throws CoreException, IOException { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath); >+ File f = new File(indexFilePath); >+ long modified = f.lastModified(); >+ IJavaProject p = this.createJavaProject("P", new String[] {}, "bin"); >+ >+ String content = new String( >+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" >+ + "<classpath>\n" >+ + "<classpathentry kind=\"src\" path=\"src a\"/>\n" >+ + "<classpathentry kind=\"src\" path=\"src x\"/>\n" >+ + "<classpathentry kind=\"lib\" path=\"" >+ + getExternalJCLPath() >+ + "\"/>\n" >+ + "<classpathentry kind=\"lib\" path=\"" >+ + jarFilePath >+ + "\">" >+ + "<attributes>\n" >+ + " <attribute name=\"index_location\" value=\"file:///" >+ + indexFilePath >+ +"\"/>\n" >+ + "</attributes>\n" >+ + "</classpathentry>\n" >+ + "<classpathentry kind=\"output\" path=\"bin\"/>\n" >+ + "</classpath>\n"); >+ >+ editFile("/P/.classpath", content); >+ p.open(null); >+ waitUntilIndexesReady(); >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ java.io.File indexFile = JavaModelManager.getIndexManager().getIndex(new Path(jarFilePath), false, false).getIndexFile(); >+ assertEquals(indexFilePath,indexFile.toString()); >+ f = new File(indexFilePath); >+ assertEquals(modified, f.lastModified()); >+ } finally { >+ deleteProject("P"); >+ new File(indexFilePath).delete(); >+ new File(jarFilePath).delete(); >+ } >+ } >+ >+ // Test changing the classpath >+ public void testChangeClasspath() throws CoreException, IOException { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath); >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}", >+ "pkg/NewTest.java", >+ "package pkg;\n" + >+ "public class NewTest {\n" + >+ " protected NewTest(int i) {}\n" + >+ "}"}, jarFilePath); >+ IJavaProject p = createJavaProject("P"); >+ Path libPath = new Path(jarFilePath); >+ >+ IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, null, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ search("NewTest", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.NewTest"); >+ >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, "file:///"+indexFilePath); >+ entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ this.resultCollector = new JavaSearchResultCollector(); >+ search("NewTest", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(""); >+ >+ entry = JavaCore.newLibraryEntry(libPath, null, null, null, null, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ this.resultCollector = new JavaSearchResultCollector(); >+ search("NewTest", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.NewTest"); >+ >+ >+ } finally { >+ deleteProject("P"); >+ new File(indexFilePath).delete(); >+ new File(jarFilePath).delete(); >+ } >+ } >+ >+ // Test changing the classpath >+ public void testChangeClasspathForInternalJar() throws CoreException, IOException { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = "/P/Test.jar"; >+ String fullJarPath = getWorkspacePath() + jarFilePath; >+ try { >+ IJavaProject p = createJavaProject("P"); >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, fullJarPath); >+ JavaIndexer.generateIndexForJar(fullJarPath, indexFilePath); >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}", >+ "pkg/NewTest.java", >+ "package pkg;\n" + >+ "public class NewTest {\n" + >+ " protected NewTest(int i) {}\n" + >+ "}"}, fullJarPath); >+ p.getProject().refreshLocal(1, null); >+ Path libPath = new Path(jarFilePath); >+ >+ IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, null, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ search("NewTest", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults("Test.jar pkg.NewTest [No source]"); >+ >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, "file:///"+indexFilePath); >+ entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ this.resultCollector = new JavaSearchResultCollector(); >+ search("NewTest", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(""); >+ >+ entry = JavaCore.newLibraryEntry(libPath, null, null, null, null, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ this.resultCollector = new JavaSearchResultCollector(); >+ search("NewTest", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults("Test.jar pkg.NewTest [No source]"); >+ } finally { >+ deleteProject("P"); >+ new File(indexFilePath).delete(); >+ } >+ } >+ >+ public void testMultipleProjects() throws CoreException, IOException { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath); >+ >+ IJavaProject p1 = createJavaProject("P1"); >+ Path libPath = new Path(jarFilePath); >+ IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, null, false); >+ setClasspath(p1, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ >+ IJavaProject p2 = createJavaProject("P2"); >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, "file:///"+indexFilePath); >+ entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false); >+ setClasspath(p2, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p1})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ >+ File indexFile = JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexFile(); >+ assertEquals(indexFilePath,indexFile.toString()); >+ >+ } finally { >+ deleteProject("P1"); >+ deleteProject("P2"); >+ new File(indexFilePath).delete(); >+ new File(jarFilePath).delete(); >+ } >+ } >+ >+ public void setContainerPath(IJavaProject p, IPath jarPath, String indexLocation) throws CoreException, BackingStoreException { >+ // Create new user library "SomeUserLibrary" >+ ClasspathContainerInitializer initializer= JavaCore.getClasspathContainerInitializer(JavaCore.USER_LIBRARY_CONTAINER_ID); >+ String libraryName = "SomeUserLibrary"; >+ IPath containerPath = new Path(JavaCore.USER_LIBRARY_CONTAINER_ID); >+ UserLibraryClasspathContainer containerSuggestion = new UserLibraryClasspathContainer(libraryName); >+ initializer.requestClasspathContainerUpdate(containerPath.append(libraryName), null, containerSuggestion); >+ >+ // Modify user library >+ IEclipsePreferences preferences = InstanceScope.INSTANCE.getNode(JavaCore.PLUGIN_ID); >+ String propertyName = JavaModelManager.CP_USERLIBRARY_PREFERENCES_PREFIX+"SomeUserLibrary"; >+ StringBuffer propertyValue = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<userlibrary systemlibrary=\"false\" version=\"1\">\r\n<archive "); >+ //String jarFullPath = getWorkspaceRoot().getLocation().append(jarFile.getFullPath()).toString(); >+ propertyValue.append(" path=\"" + jarPath + "\">\r\n"); >+ propertyValue.append(" <attributes>\r\n"); >+ propertyValue.append(" <attribute name=\"index_location\" value=\""); >+ propertyValue.append(indexLocation); >+ propertyValue.append("\"/>\r\n</attributes>\r\n"); >+ propertyValue.append("</archive>\r\n"); >+ propertyValue.append("</userlibrary>\r\n"); >+ preferences.put(propertyName, propertyValue.toString()); >+ preferences.flush(); >+ >+ IClasspathEntry[] entries = p.getRawClasspath(); >+ int length = entries.length; >+ System.arraycopy(entries, 0, entries = new IClasspathEntry[length+1], 0, length); >+ entries[length] = JavaCore.newContainerEntry(containerSuggestion.getPath()); >+ p.setRawClasspath(entries, null); >+ } >+ >+ public void testUserLibraryIndex() throws IOException, CoreException, BackingStoreException { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath); >+ long modified = new File(indexFilePath).lastModified(); >+ >+ IJavaProject p = createJavaProject("P"); >+ >+ Path libPath = new Path(jarFilePath); >+ setContainerPath(p, libPath, "file:///"+indexFilePath); >+ >+ waitUntilIndexesReady(); >+ >+ // Test that specified index file is really used >+ java.io.File indexFile = JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexFile(); >+ assertEquals("Specified index file is not being used", indexFilePath,indexFile.toString()); >+ >+ // Test that search works properly >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ // Ensure that the index file is not modified >+ assertEquals(modified, new File(indexFilePath).lastModified()); >+ >+ simulateExitRestart(); >+ getJavaModel().refreshExternalArchives(null,null); >+ waitUntilIndexesReady(); >+ >+ // Test that specified index file is really used >+ indexFile = JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexFile(); >+ assertEquals("Specified index file is not being used", indexFilePath,indexFile.toString()); >+ >+ // Test that search works properly >+ this.resultCollector = new JavaSearchResultCollector(); >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ // Ensure that the index file is not modified >+ assertEquals(modified, new File(indexFilePath).lastModified()); >+ } finally { >+ deleteProject("P"); >+ new File(indexFilePath).delete(); >+ new File(jarFilePath).delete(); >+ } >+ } >+ >+ // Test that it works if the index file is in the jar file >+ public void testIndexInJar() throws IOException, CoreException { >+ String indexFilePath = getExternalResourcePath("Test.index"); >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ String indexZipPath = getExternalResourcePath("TestIndex.zip"); >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ >+ JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath); >+ Util.zipFiles(new File[]{new File(indexFilePath)}, indexZipPath); >+ >+ IJavaProject p = createJavaProject("P"); >+ Path libPath = new Path(jarFilePath); >+ String url = "jar:file:"+indexZipPath+"!/Test.index"; >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, url); >+ IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ >+ assertEquals(url,JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexLocation().getUrl().toString()); >+ >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ >+ simulateExitRestart(); >+ getJavaModel().refreshExternalArchives(null,null); >+ waitUntilIndexesReady(); >+ >+ this.resultCollector = new JavaSearchResultCollector(); >+ assertEquals(url,JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexLocation().getUrl().toString()); >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ } finally { >+ deleteProject("P"); >+ new File(indexZipPath).delete(); >+ new File(jarFilePath).delete(); >+ } >+ } >+ >+ // Test index file in platform >+ public void testPlatformJarIndexFile() throws CoreException, IOException { >+ String indexFilePath = null; >+ String jarFilePath = getExternalResourcePath("Test.jar"); >+ String indexUrl = "platform:/resource/ForIndex/Test.index.zip!/Test.index"; >+ try { >+ createJar(new String[] { >+ "pkg/Test.java", >+ "package pkg;\n" + >+ "public class Test {\n" + >+ " protected Test(int i) {}\n" + >+ "}"}, jarFilePath); >+ >+ IProject indexProj = createProject("ForIndex"); >+ indexFilePath = indexProj.getProject().getLocation().append("Test.index").toFile().getAbsolutePath(); >+ JavaIndexer.generateIndexForJar(jarFilePath, indexFilePath); >+ Util.zipFiles(new File[]{new File(indexFilePath)}, indexFilePath+".zip"); >+ >+ IJavaProject p = createJavaProject("P"); >+ Path libPath = new Path(jarFilePath); >+ IClasspathAttribute attribute = JavaCore.newClasspathAttribute(IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME, indexUrl); >+ IClasspathEntry entry = JavaCore.newLibraryEntry(libPath, null, null, null, new IClasspathAttribute[]{attribute}, false); >+ setClasspath(p, new IClasspathEntry[] {entry}); >+ waitUntilIndexesReady(); >+ >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ >+ URL url = JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexLocation().getUrl(); >+ assertEquals(indexUrl, url.toString()); >+ >+ simulateExitRestart(); >+ getJavaModel().refreshExternalArchives(null,null); >+ waitUntilIndexesReady(); >+ >+ this.resultCollector = new JavaSearchResultCollector(); >+ search("Test", TYPE, DECLARATIONS, EXACT_RULE, SearchEngine.createJavaSearchScope(new IJavaElement[]{p})); >+ assertSearchResults(getExternalPath() + "Test.jar pkg.Test"); >+ >+ url = JavaModelManager.getIndexManager().getIndex(libPath, false, false).getIndexLocation().getUrl(); >+ assertEquals(indexUrl, url.toString()); >+ } finally { >+ deleteProject("P"); >+ if (indexFilePath != null) { >+ new File(indexFilePath).delete(); >+ new File(indexFilePath+".zip").delete(); >+ } >+ new File(jarFilePath).delete(); >+ deleteProject("ForIndex"); >+ } >+ } >+} >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaProjectTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaProjectTests.java >index 6357803..a7388ab 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaProjectTests.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaProjectTests.java >@@ -37,7 +37,7 @@ > super(name); > } > static { >-// TESTS_NAMES = new String[] { "testAddExternalLibFolder6" }; >+// TESTS_NAMES = new String[] { "testBug360164" }; > } > public static Test suite() { > TestSuite suite = (TestSuite) buildModelTestSuite(JavaProjectTests.class); >@@ -2389,4 +2389,102 @@ > deleteProject("JavaProjectTestsInvalidProject"); > } > } >+// Bug 360164 - Compile error in XSDImpl >+// test that we can tolerate if a 1.4 project refers to an enum inside a library. >+public void testBug360164() throws IOException, CoreException { >+ String libPath = getWorkspacePath()+"JavaProjectTests/bin/bug360164.jar"; >+ try { >+ this.createJavaProject("P", new String[] {"src"}, new String[] {"JCL_LIB", libPath}, "bin", JavaCore.VERSION_1_4); >+ IFile file = createFile("/P/src/X.java", >+ "import p360164.Provider;\n" + >+ "import p360164.MyEnum;\n" + >+ "public class X {\n" + >+ " int foo(Provider p) {\n" + >+ " MyEnum e = p.getE();\n" + >+ " switch (e.getValue()) {\n" + >+ " case MyEnum.ONE_COMPAT: return 1;\n" + >+ " case MyEnum.TWO_COMPAT: return 2;\n" + >+ " }\n" + >+ " return 0;\n" + >+ " }\n" + >+ "}" >+ ); >+ ICompilationUnit unit = (ICompilationUnit)JavaCore.create(file); >+ ProblemRequestor problemRequestor = new ProblemRequestor(); >+ WorkingCopyOwner owner = newWorkingCopyOwner(problemRequestor); >+ unit.getWorkingCopy(owner, null); >+ assertProblems("Unexpected problems", >+ "----------\n" + >+ "----------\n", >+ problemRequestor); >+ } finally { >+ this.deleteProject("P"); >+ } >+} >+// Bug 360164 - Compile error in XSDImpl >+// test that we still report the missing superclass when resolving non-local methods >+public void testBug360164a() throws IOException, CoreException { >+ String libPath = getWorkspacePath()+"JavaProjectTests/bin/bug360164.jar"; >+ try { >+ this.createJavaProject("P", new String[] {"src"}, new String[] {"JCL_LIB", libPath}, "bin", JavaCore.VERSION_1_4); >+ IFile file = createFile("/P/src/X.java", >+ "import p360164.Provider;\n" + >+ "import p360164.MyEnum;\n" + >+ "public class X {\n" + >+ " String foo(Provider p) {\n" + >+ " MyEnum e = p.getE();\n" + >+ " return e.toString();\n" + >+ " }\n" + >+ "}" >+ ); >+ ICompilationUnit unit = (ICompilationUnit)JavaCore.create(file); >+ ProblemRequestor problemRequestor = new ProblemRequestor(); >+ WorkingCopyOwner owner = newWorkingCopyOwner(problemRequestor); >+ unit.getWorkingCopy(owner, null); >+ assertProblems("Unexpected problems", >+ "----------\n" + >+ "1. ERROR in /P/src/X.java\n" + >+ "The type java.lang.Enum cannot be resolved. It is indirectly referenced from required .class files\n" + >+ "----------\n", >+ problemRequestor); >+ } finally { >+ this.deleteProject("P"); >+ } >+} >+// Bug 360317 - [compiler] report switch over enum in 1.4- mode >+public void testBug360317() throws IOException, CoreException { >+ // use the setup from testBug360164(): >+ String libPath = getWorkspacePath()+"JavaProjectTests/bin/bug360164.jar"; >+ try { >+ this.createJavaProject("P", new String[] {"src"}, new String[] {"JCL_LIB", libPath}, "bin", JavaCore.VERSION_1_4); >+ String sourceX = "import p360164.Provider;\n" + >+ "import p360164.MyEnum;\n" + >+ "public class X {\n" + >+ " int foo(Provider p) {\n" + >+ " MyEnum e = p.getE();\n" + >+ " switch (e) {\n" + >+ " case ONE: return 1;\n" + >+ " case TWO: return 2;\n" + >+ " }\n" + >+ " return 0;\n" + >+ " }\n" + >+ "}"; >+ IFile file = createFile("/P/src/X.java", sourceX); >+ ICompilationUnit unit = (ICompilationUnit)JavaCore.create(file); >+ ProblemRequestor problemRequestor = new ProblemRequestor(); >+ problemRequestor.initialize(sourceX.toCharArray()); >+ WorkingCopyOwner owner = newWorkingCopyOwner(problemRequestor); >+ unit.getWorkingCopy(owner, null); >+ assertProblems("Unexpected problems", >+ "----------\n" + >+ "1. ERROR in /P/src/X.java (at line 6)\n" + >+ " switch (e) {\n" + >+ " ^\n" + >+ "Cannot switch on an enum value for source level below 1.5. Only convertible int values are permitted\n" + >+ "----------\n", >+ problemRequestor); >+ } finally { >+ this.deleteProject("P"); >+ } >+} > } >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java >index f18fa34..4ab96d2 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -69,7 +69,6 @@ > import org.eclipse.jdt.core.search.TypeReferenceMatch; > import org.eclipse.jdt.core.tests.util.Util; > import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; >-import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; > import org.eclipse.jdt.internal.core.ClassFile; > import org.eclipse.jdt.internal.core.JavaModelManager; > import org.eclipse.jdt.internal.core.SourceMethod; >@@ -94,7 +93,7 @@ > // Debug > static { > // org.eclipse.jdt.internal.core.search.BasicSearchEngine.VERBOSE = true; >-// TESTS_NAMES = new String[] {"testBug306223"}; >+// TESTS_NAMES = new String[] {"testBug324189d"}; > } > > public JavaSearchBugsTests(String name) { >@@ -710,6 +709,8 @@ > suite.addTest(new JavaSearchBugsTests("testBug350885")); > suite.addTest(new JavaSearchBugsTests("testBug349683")); > suite.addTest(new JavaSearchBugsTests("testBug345807")); >+ suite.addTest(new JavaSearchBugsTests("testBug355605")); >+ suite.addTest(new JavaSearchBugsTests("testBug241834")); > return suite; > } > class TestCollector extends JavaSearchResultCollector { >@@ -11579,9 +11580,9 @@ > */ > public void testBug286379c() throws CoreException { > class TestResourceChangeListener implements IResourceChangeListener { >- boolean valid = false; >+ boolean toRemPresent = false; > public void resourceChanged(IResourceChangeEvent event) { >- this.valid = validate(event.getDelta()); >+ this.toRemPresent = validate(event.getDelta()); > } > /* > * Ensure that the listener receives a delta concerning the resource >@@ -11604,17 +11605,6 @@ > return false; > } > } >- // print statement to debug random failures of this test >- JavaModelManager.DEBUG_302850 = true; >- System.out.println("================================================================================"); >- System.out.println("Starting test JavaSearchBugTests.testBug286379c()..."); >- System.out.println(" - Default Options at test start:"); >- System.out.println(Util.indentString(new CompilerOptions(JavaCore.getDefaultOptions()).toString(), 1)); >- System.out.println(" - Options at test start:"); >- System.out.println(" + Task tags: " + JavaCore.getOption(JavaCore.COMPILER_TASK_TAGS)); >- System.out.println(" + Task priorities: " + JavaCore.getOption(JavaCore.COMPILER_TASK_PRIORITIES)); >- System.out.println(" + Forbidden reference: " + JavaCore.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE)); >- System.out.println(Util.indentString(new CompilerOptions(JavaCore.getOptions()).toString(), 2)); > > IContentType javaContentType = Platform.getContentTypeManager().getContentType(JavaCore.JAVA_SOURCE_CONTENT_TYPE); > TestResourceChangeListener changeListener = new TestResourceChangeListener(); >@@ -11644,7 +11634,7 @@ > // fail as we don't get any specific event from the platform to refresh the indexes. > // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=118619 > int counter = 0; >- while (!changeListener.valid) { >+ while (!changeListener.toRemPresent) { > try { > Thread.sleep(100); > } >@@ -11657,21 +11647,9 @@ > // Wait to be sure that indexes are ready after the new resource was added > waitUntilIndexesReady(); > >- // print statement to debug random failures of this test >- System.out.println(" - Options before first exit:"); >- System.out.println(" + Task tags: " + JavaCore.getOption(JavaCore.COMPILER_TASK_TAGS)); >- System.out.println(" + Task priorities: " + JavaCore.getOption(JavaCore.COMPILER_TASK_PRIORITIES)); >- System.out.println(" + Forbidden reference: " + JavaCore.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE)); >- System.out.println(Util.indentString(new CompilerOptions(JavaCore.getOptions()).toString(), 2)); > // Restart to let the indexes to be refreshed > simulateExit(); > simulateRestart(); >- // print statement to debug random failures of this test >- System.out.println(" - Options after first restart:"); >- System.out.println(" + Task tags: " + JavaCore.getOption(JavaCore.COMPILER_TASK_TAGS)); >- System.out.println(" + Task priorities: " + JavaCore.getOption(JavaCore.COMPILER_TASK_PRIORITIES)); >- System.out.println(" + Forbidden reference: " + JavaCore.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE)); >- System.out.println(Util.indentString(new CompilerOptions(JavaCore.getOptions()).toString(), 2)); > waitUntilIndexesReady(); > > // Search for the new type with new extension >@@ -11689,22 +11667,23 @@ > false /*only assume*/); > > // Delete the file specification >+ changeListener.toRemPresent = true; > javaContentType.removeFileSpec("torem", IContentType.FILE_EXTENSION_SPEC); >+ counter = 0; >+ while (changeListener.toRemPresent) { >+ try { >+ Thread.sleep(100); >+ } >+ catch (InterruptedException ie) { >+ // skip >+ } >+ assertTrue("We should have got a resource event within a 10s delay!", counter++ < 100); >+ } >+ waitUntilIndexesReady(); > >- // print statement to debug random failures of this test >- System.out.println(" - Options before second exit:"); >- System.out.println(" + Task tags: " + JavaCore.getOption(JavaCore.COMPILER_TASK_TAGS)); >- System.out.println(" + Task priorities: " + JavaCore.getOption(JavaCore.COMPILER_TASK_PRIORITIES)); >- System.out.println(" + Forbidden reference: " + JavaCore.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE)); >- System.out.println(Util.indentString(new CompilerOptions(JavaCore.getOptions()).toString(), 2)); > // Restarting should update the index file to remove the references of any .torem files > simulateExit(); >- simulateRestart(); >- // print statement to debug random failures of this test >- System.out.println(" - Options after second restart:"); >- System.out.println(" + Task tags: " + JavaCore.getOption(JavaCore.COMPILER_TASK_TAGS)); >- System.out.println(" + Task priorities: " + JavaCore.getOption(JavaCore.COMPILER_TASK_PRIORITIES)); >- System.out.println(" + Forbidden reference: " + JavaCore.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE)); >+ simulateRestart(); > waitUntilIndexesReady(); > > // Search for the new type with new extension >@@ -11717,24 +11696,11 @@ > IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, > null); > assertSearchResults("No search results expected", "", collector); >- System.out.println(" - Options after search:"); >- System.out.println(" + Task tags: " + JavaCore.getOption(JavaCore.COMPILER_TASK_TAGS)); >- System.out.println(" + Task priorities: " + JavaCore.getOption(JavaCore.COMPILER_TASK_PRIORITIES)); >- System.out.println(" + Forbidden reference: " + JavaCore.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE)); >- System.out.println(Util.indentString(new CompilerOptions(JavaCore.getOptions()).toString(), 2)); > } finally { > getWorkspace().removeResourceChangeListener(changeListener); > if (javaContentType != null) > javaContentType.removeFileSpec("torem", IContentType.FILE_EXTENSION_SPEC); > deleteProject("P"); >- System.out.println(" - Options at test end:"); >- System.out.println(" + Task tags: " + JavaCore.getOption(JavaCore.COMPILER_TASK_TAGS)); >- System.out.println(" + Task priorities: " + JavaCore.getOption(JavaCore.COMPILER_TASK_PRIORITIES)); >- System.out.println(" + Forbidden reference: " + JavaCore.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE)); >- System.out.println(Util.indentString(new CompilerOptions(JavaCore.getOptions()).toString(), 2)); >- System.out.println(" - Default Options at test end:"); >- System.out.println(Util.indentString(new CompilerOptions(JavaCore.getDefaultOptions()).toString(), 2)); >- JavaModelManager.DEBUG_302850 = false; > } > } > >@@ -13434,7 +13400,7 @@ > }, > new HashMap(), > libPath); >- IJavaProject javaProject = createJavaProject("P", new String[0], new String[] {libPath}, ""); >+ IJavaProject javaProject = createJavaProject("P", new String[0], new String[] {libPath, "JCL_LIB"}, ""); > waitUntilIndexesReady(); > int mask = IJavaSearchScope.APPLICATION_LIBRARIES | IJavaSearchScope.SOURCES ; > IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[] { javaProject }, mask); >@@ -13713,4 +13679,69 @@ > deleteProject("Project2"); > } > } >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=355605 >+public void testBug355605() throws CoreException { >+ try { >+ createJavaProject("P"); >+ >+ String fileContent = >+ "public class X { \n" >+ + "class R {\n" >+ + " class S {\n" >+ + " void setInfo(String x) {\n" >+ + " }\n" >+ + " }\n" >+ + " class T {\n" >+ + " }\n" >+ + " T t = new T() {\n" >+ + " S s = new S() {\n" >+ + " void myMethod() {\n" >+ + " setInfo(\"a\");\n" >+ + " }\n" >+ + " };// S ends\n" >+ + " };\n" >+ + "}\n" >+ + "}\n" ; >+ createFile("/P/X.java", fileContent); >+ >+ waitUntilIndexesReady(); >+ this.resultCollector = new TestCollector(); >+ this.resultCollector.showAccuracy(true); >+ ICompilationUnit unit = getCompilationUnit("/P/X.java"); >+ IMethod method = selectMethod(unit, "myMethod", 1); >+ IJavaSearchScope hierarchyScope = SearchEngine.createHierarchyScope((IType)method.getParent()); >+ search(method, IMPLEMENTORS, EXACT_RULE, hierarchyScope, this.resultCollector); >+ assertSearchResults("Unexpected search results!", "X.java void X$R.t:<anonymous>#1.s:<anonymous>#1.myMethod() [myMethod] EXACT_MATCH", this.resultCollector); >+ >+ } finally { >+ deleteProject("P"); >+ } >+} >+/** >+ * @bug 241834: [search] ClassCastException during move class refactoring >+ * @test that search for declarations of referenced types doesn't cause CCE >+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=241834" >+ */ >+public void testBug241834() throws CoreException { >+ try { >+ IJavaProject project = createJavaProject("P"); >+ project.setOption(JavaCore.COMPILER_DOC_COMMENT_SUPPORT, JavaCore.ENABLED); >+ createFolder("/P/pkg"); >+ createFile("/P/pkg/Foo.java", >+ "package pkg;\n"+ >+ "/**\n" + >+ " * {@link missing.Foo}\n" + >+ " */\n" + >+ "public class Foo {\n" + >+ "}\n"); >+ waitUntilIndexesReady(); >+ IType type = getCompilationUnit("/P/pkg/Foo.java").getType("Foo"); >+ searchDeclarationsOfReferencedTypes(type, this.resultCollector); >+ assertSearchResults(""); >+ } finally { >+ deleteProject("P"); >+ >+ } >+} >+// Add new tests in JavaSearchBugsTests2 > } >\ No newline at end of file >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests2.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests2.java >new file mode 100644 >index 0000000..0052f7a >--- /dev/null >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests2.java >@@ -0,0 +1,484 @@ >+/******************************************************************************* >+ * Copyright (c) 2012 IBM Corporation 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+ >+package org.eclipse.jdt.core.tests.model; >+ >+import java.io.IOException; >+import java.util.ArrayList; >+import java.util.List; >+ >+import junit.framework.Test; >+ >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.jdt.core.IJavaElement; >+import org.eclipse.jdt.core.IJavaProject; >+import org.eclipse.jdt.core.IMethod; >+import org.eclipse.jdt.core.IType; >+import org.eclipse.jdt.core.search.IJavaSearchConstants; >+import org.eclipse.jdt.core.search.IJavaSearchScope; >+import org.eclipse.jdt.core.search.SearchEngine; >+import org.eclipse.jdt.core.search.SearchMatch; >+import org.eclipse.jdt.core.search.SearchPattern; >+ >+// The size of JavaSearchBugsTests.java is very big, Hence continuing here. >+public class JavaSearchBugsTests2 extends AbstractJavaSearchTests { >+ >+ public JavaSearchBugsTests2(String name) { >+ super(name); >+ this.endChar = ""; >+ } >+ >+ static { >+ //TESTS_NAMES = new String[] {"testBug123836"}; >+ } >+ >+ public static Test suite() { >+ return buildModelTestSuite(JavaSearchBugsTests2.class); >+ } >+ >+ class TestCollector extends JavaSearchResultCollector { >+ public List matches = new ArrayList(); >+ >+ public void acceptSearchMatch(SearchMatch searchMatch) throws CoreException { >+ super.acceptSearchMatch(searchMatch); >+ this.matches.add(searchMatch); >+ } >+ } >+ >+ protected void setUp() throws Exception { >+ super.setUp(); >+ this.resultCollector = new TestCollector(); >+ this.resultCollector.showAccuracy(true); >+ } >+ >+ /** >+ * Test that missing types in the class shouldn't impact the search of a type in an inner class >+ */ >+ public void testBug362633() throws CoreException, IOException { >+ try { >+ IJavaProject p = createJavaProject("P", new String[] {}, new String[] { "/P/lib325418.jar", "JCL15_LIB" }, "", "1.5"); >+ org.eclipse.jdt.core.tests.util.Util.createJar(new String[] { >+ "p325418M/Missing.java", >+ "package p325418M;\n" + >+ "public class Missing{}\n" }, >+ p.getProject().getLocation().append("lib325418M.jar").toOSString(), "1.5"); >+ >+ org.eclipse.jdt.core.tests.util.Util.createJar( >+ new String[] { >+ "p325418/Test.java", >+ "package p325418;\n" + >+ "public class Test{\n" + >+ " public void foo(p325418M.Missing a) {}\n" + >+ " public <T> T foo(int a) {\n" + >+ " return new Inner<T>() {T run() { return null; }}.run();\n" + >+ " }\n" + "}\n", >+ "p325418/Inner.java", >+ "package p325418;\n" + >+ "abstract class Inner <T> {\n" + >+ " abstract T run();\n" + "}\n" }, >+ null, >+ p.getProject().getLocation().append("lib325418.jar").toOSString(), >+ new String[] { p.getProject().getLocation().append("lib325418M.jar").toOSString() }, >+ "1.5"); >+ refresh(p); >+ int mask = IJavaSearchScope.APPLICATION_LIBRARIES | IJavaSearchScope.SOURCES; >+ IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[] { p }, mask); >+ search("Inner.run()", IJavaSearchConstants.METHOD, IJavaSearchConstants.DECLARATIONS, scope, this.resultCollector); >+ assertSearchResults( >+ "Unexpected search results!", >+ "lib325418.jar T p325418.Inner.run() [No source] EXACT_MATCH\n" + >+ "lib325418.jar T p325418.<anonymous>.run() [No source] EXACT_MATCH", >+ this.resultCollector); >+ } finally { >+ deleteProject("P"); >+ } >+ } >+ >+ /** >+ * @bug 123836: [1.5][search] for references to overriding method with bound type variable is not polymorphic >+ * @test Search for references to an overridden method with bound variables should yield. >+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=123836" >+ */ >+ public void testBug123836a() throws CoreException { >+ IJavaProject project = null; >+ try >+ { >+ project = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB"}, "","1.5"); >+ createFile("/P/Sub.java", >+ "abstract class Sup<C> {\n" + >+ " protected void m(C classifier) {}\n"+ >+ " public void use(C owner) { m (owner); }\n" + >+ "}\n" + >+ "public class Sub extends Sup<String>{\n" + >+ " @Override\n"+ >+ " protected void m(String classifier) {}\n"+ >+ "}\n"); >+ IType type = getCompilationUnit("/P/Sub.java").getType("Sub"); >+ IMethod method = type.getMethod("m", new String[]{"QString;"}); >+ search(method, REFERENCES, EXACT_RULE, SearchEngine.createWorkspaceScope(), this.resultCollector); >+ assertSearchResults("Sub.java void Sup.use(C) [m (owner)] EXACT_MATCH"); >+ } finally { >+ deleteProject(project); >+ } >+ } >+ // Search for a non-overriden method with same name as which could have been overriden should >+ // not have results >+ public void testBug123836b() throws CoreException { >+ IJavaProject project = null; >+ try >+ { >+ project = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB"}, "","1.5"); >+ createFile("/P/Sub.java", >+ "abstract class Sup<C> {\n" + >+ " protected void m(C classifier) {}\n"+ >+ " public void use(C owner) { m (owner); }\n" + >+ "}\n" + >+ "public class Sub extends Sup<String>{\n" + >+ " @Override\n"+ >+ " protected void m(String classifier) {}\n"+ >+ " protected void m(Sub classifier) {}\n"+ >+ "}\n" ); >+ // search >+ IType type = getCompilationUnit("/P/Sub.java").getType("Sub"); >+ IMethod method = type.getMethod("m", new String[]{"QSub;"}); >+ search(method, REFERENCES, EXACT_RULE, SearchEngine.createWorkspaceScope(), this.resultCollector); >+ assertSearchResults(""); >+ >+ } finally { >+ deleteProject(project); >+ } >+ } >+ // another variant of the testcase >+ public void testBug123836c() throws CoreException { >+ IJavaProject project = null; >+ try >+ { >+ // create the common project and create an interface >+ project = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB"}, "","1.5"); >+ createFile("/P/Test.java", >+ "class Test {\n"+ >+ " void calc(Property prop, Property<? extends Serializable> p2) {\n"+ >+ " prop.compute(null);\n"+ >+ " p2.compute(null);\n"+ >+ " }\n"+ >+ "}\n"+ >+ "abstract class Property<E> {\n"+ >+ " public abstract void compute(E e);\n"+ >+ "}\n"+ >+ "class StringProperty extends Property<String> {\n"+ >+ " @Override public void compute(String e) {\n"+ >+ " System.out.println(e);\n"+ >+ " }"); >+ IType type = getCompilationUnit("/P/Test.java").getType("StringProperty"); >+ IMethod method = type.getMethod("compute", new String[]{"QString;"}); >+ search(method, REFERENCES, EXACT_RULE, SearchEngine.createWorkspaceScope(), this.resultCollector); >+ assertSearchResults("Test.java void Test.calc(Property, Property<? extends Serializable>) [compute(null)] EXACT_MATCH\n" + >+ "Test.java void Test.calc(Property, Property<? extends Serializable>) [compute(null)] EXACT_MATCH"); >+ } finally { >+ deleteProject(project); >+ } >+ } >+ // Test inner class >+ public void testBug123836d() throws CoreException { >+ IJavaProject project = null; >+ try >+ { >+ // create the common project and create an interface >+ project = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB"}, "","1.5"); >+ createFile("/P/Test.java", >+ "class Test {\n"+ >+ " void calc(Property prop, Property<? extends Serializable> p2) {\n"+ >+ " prop.compute(null);\n"+ >+ " p2.compute(null);\n"+ >+ " }\n"+ >+ " class StringProperty extends Property<String> {\n"+ >+ " @Override public void compute(String e) {\n"+ >+ " System.out.println(e);\n"+ >+ " }\n"+ >+ "}\n"+ >+ "abstract class Property<E> {\n"+ >+ " public abstract void compute(E e);\n"+ >+ "}"); >+ >+ IType type = getCompilationUnit("/P/Test.java").getType("Test").getType("StringProperty"); >+ IMethod method = type.getMethod("compute", new String[]{"QString;"}); >+ search(method, REFERENCES, EXACT_RULE, SearchEngine.createWorkspaceScope(), this.resultCollector); >+ assertSearchResults("Test.java void Test.calc(Property, Property<? extends Serializable>) [compute(null)] EXACT_MATCH\n" + >+ "Test.java void Test.calc(Property, Property<? extends Serializable>) [compute(null)] EXACT_MATCH"); >+ } finally { >+ deleteProject(project); >+ } >+ } >+ // Test local class >+ public void testBug123836e() throws CoreException { >+ IJavaProject project = null; >+ try >+ { >+ // create the common project and create an interface >+ project = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB"}, "","1.5"); >+ createFile("/P/Test.java", >+ "class Test {\n"+ >+ " void calc(Property prop, Property<? extends Serializable> p2) {\n"+ >+ " prop.compute(null);\n"+ >+ " p2.compute(null);\n"+ >+ " class StringProperty extends Property<String> {\n"+ >+ " @Override public void compute(String e) {\n"+ >+ " System.out.println(e);\n"+ >+ " }\n"+ >+ " }\n"+ >+ " }\n"+ >+ "}\n"+ >+ "abstract class Property<E> {\n"+ >+ " public abstract void compute(E e);\n"+ >+ "}"); >+ IMethod method = selectMethod(getCompilationUnit("/P/Test.java"), "compute", 3); >+ search(method, REFERENCES, EXACT_RULE, SearchEngine.createWorkspaceScope(), this.resultCollector); >+ assertSearchResults("Test.java void Test.calc(Property, Property<? extends Serializable>) [compute(null)] EXACT_MATCH\n" + >+ "Test.java void Test.calc(Property, Property<? extends Serializable>) [compute(null)] EXACT_MATCH"); >+ } finally { >+ deleteProject(project); >+ } >+ } >+ // test inner class >+ public void testBug123836f() throws CoreException { >+ IJavaProject project = null; >+ try >+ { >+ // create the common project and create an interface >+ project = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB"}, "","1.5"); >+ createFile("/P/Test.java", >+ "class Test {\n"+ >+ " void calc(Property prop, Property<? extends Serializable> p2) {\n"+ >+ " prop.compute(null);\n"+ >+ " p2.compute(null);\n"+ >+ " new Property<String>() {\n"+ >+ " @Override public void compute(String e) {\n"+ >+ " System.out.println(e);\n"+ >+ " }\n"+ >+ " };\n"+ >+ " }\n"+ >+ "}\n"+ >+ "abstract class Property<E> {\n"+ >+ " public abstract void compute(E e);\n"+ >+ "}"); >+ IMethod method = selectMethod(getCompilationUnit("/P/Test.java"), "compute", 3); >+ search(method, REFERENCES, EXACT_RULE, SearchEngine.createWorkspaceScope(), this.resultCollector); >+ assertSearchResults("Test.java void Test.calc(Property, Property<? extends Serializable>) [compute(null)] EXACT_MATCH\n" + >+ "Test.java void Test.calc(Property, Property<? extends Serializable>) [compute(null)] EXACT_MATCH"); >+ } finally { >+ deleteProject(project); >+ } >+ } >+ // test in initializer block >+ public void testBug123836g() throws CoreException { >+ IJavaProject project = null; >+ try >+ { >+ // create the common project and create an interface >+ project = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB"}, "","1.5"); >+ createFile("/P/Test.java", >+ "class Test {\n"+ >+ " {\n" + >+ " new Property<String>() {\n" + >+ " @Override public void compute(String e) {}\n" + >+ " };\n"+ >+ " }\n"+ >+ " void calc(Property prop, Property<? extends Serializable> p2) {\n"+ >+ " prop.compute(null);\n"+ >+ " p2.compute(null);\n"+ >+ " }\n"+ >+ "}\n"+ >+ "abstract class Property<E> {\n"+ >+ " public abstract void compute(E e);\n"+ >+ "}"); >+ IMethod method = selectMethod(getCompilationUnit("/P/Test.java"), "compute", 1); >+ search(method, REFERENCES, EXACT_RULE, SearchEngine.createWorkspaceScope(), this.resultCollector); >+ assertSearchResults("Test.java void Test.calc(Property, Property<? extends Serializable>) [compute(null)] EXACT_MATCH\n" + >+ "Test.java void Test.calc(Property, Property<? extends Serializable>) [compute(null)] EXACT_MATCH"); >+ } finally { >+ deleteProject(project); >+ } >+ } >+ // test in static initializer >+ public void testBug123836h() throws CoreException { >+ IJavaProject project = null; >+ try >+ { >+ // create the common project and create an interface >+ project = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB"}, "","1.5"); >+ createFile("/P/Test.java", >+ "class Test {\n"+ >+ " static {\n" + >+ " new Property<String>() {\n" + >+ " @Override public void compute(String e) {}\n" + >+ " };\n"+ >+ " }\n"+ >+ " void calc(Property prop, Property<? extends Serializable> p2) {\n"+ >+ " prop.compute(null);\n"+ >+ " p2.compute(null);\n"+ >+ " }\n"+ >+ "}\n"+ >+ "abstract class Property<E> {\n"+ >+ " public abstract void compute(E e);\n"+ >+ "}"); >+ IMethod method = selectMethod(getCompilationUnit("/P/Test.java"), "compute", 1); >+ search(method, REFERENCES, EXACT_RULE, SearchEngine.createWorkspaceScope(), this.resultCollector); >+ assertSearchResults("Test.java void Test.calc(Property, Property<? extends Serializable>) [compute(null)] EXACT_MATCH\n" + >+ "Test.java void Test.calc(Property, Property<? extends Serializable>) [compute(null)] EXACT_MATCH"); >+ } finally { >+ deleteProject(project); >+ } >+ } >+ // test in static initializer >+ public void testBug123836i() throws CoreException { >+ IJavaProject project = null; >+ try >+ { >+ // create the common project and create an interface >+ project = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB"}, "","1.5"); >+ createFile("/P/Test.java", >+ "class Test {\n"+ >+ " Property <?>p = new Property<String>() {\n" + >+ " @Override public void compute(String e) {}\n" + >+ " };\n"+ >+ " void calc(Property prop, Property<? extends Serializable> p2) {\n"+ >+ " prop.compute(null);\n"+ >+ " p2.compute(null);\n"+ >+ " }\n"+ >+ "}\n"+ >+ "abstract class Property<E> {\n"+ >+ " public abstract void compute(E e);\n"+ >+ "}"); >+ IMethod method = selectMethod(getCompilationUnit("/P/Test.java"), "compute", 1); >+ search(method, REFERENCES, EXACT_RULE, SearchEngine.createWorkspaceScope(), this.resultCollector); >+ assertSearchResults("Test.java void Test.calc(Property, Property<? extends Serializable>) [compute(null)] EXACT_MATCH\n" + >+ "Test.java void Test.calc(Property, Property<? extends Serializable>) [compute(null)] EXACT_MATCH"); >+ } finally { >+ deleteProject(project); >+ } >+ } >+ public void testBug123836j() throws CoreException { >+ IJavaProject project = null; >+ try >+ { >+ // create the common project and create an interface >+ project = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB"}, "","1.5"); >+ createFile("/P/Test.java", >+ "class Test {\n"+ >+ " void calc(Property prop, Property<? extends Serializable> p2) {\n"+ >+ " prop.compute(null);\n"+ >+ " p2.compute(null);\n"+ >+ " }\n"+ >+ "}\n"+ >+ "abstract class Property<E> {\n"+ >+ " public abstract void compute(E e);\n"+ >+ "}\n"+ >+ "class StringProperty extends Property<String> {\n"+ >+ " @Override public void compute(String e) {\n"+ >+ " new Property<String>() {\n"+ >+ " @Override public void compute(String e) {\n"+ >+ " new Property<String>() {\n"+ >+ " @Override public void compute(String e) {}\n"+ >+ " };\n"+ >+ " }\n"+ >+ " };\n"+ >+ " }\n"+ >+ "}"); >+ IMethod method = selectMethod(getCompilationUnit("/P/Test.java"), "compute", 6); >+ search(method, REFERENCES, EXACT_RULE, SearchEngine.createWorkspaceScope(), this.resultCollector); >+ assertSearchResults("Test.java void Test.calc(Property, Property<? extends Serializable>) [compute(null)] EXACT_MATCH\n" + >+ "Test.java void Test.calc(Property, Property<? extends Serializable>) [compute(null)] EXACT_MATCH"); >+ } finally { >+ deleteProject(project); >+ } >+ } >+ // test search of name >+ public void _testBug123836g1() throws CoreException { >+ IJavaProject project = null; >+ try >+ { >+ // create the common project and create an interface >+ project = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB"}, "","1.5"); >+ createFile("/P/Sub.java", >+ "abstract class Sup<C> {\n" + >+ " protected void m(C classifier) {}\n"+ >+ " public void use(C owner) { m (owner); }\n" + >+ "}\n" + >+ "public class Sub extends Sup<String>{\n" + >+ " @Override\n"+ >+ " protected void m(String classifier) {}\n"+ >+ " protected void m(Sub classifier) {}\n"+ >+ "}\n" ); >+ waitUntilIndexesReady(); >+ // search >+ SearchPattern pattern = SearchPattern.createPattern("Sub.m(String)", METHOD, REFERENCES, EXACT_RULE); >+ search(pattern, SearchEngine.createWorkspaceScope(), this.resultCollector); >+ assertSearchResults("Sub.java void Sup.use(C) [m (owner)] EXACT_MATCH"); >+ >+ } finally { >+ deleteProject(project); >+ } >+ } >+ // test search of name (negative) >+ public void _testBug123836h1() throws CoreException { >+ IJavaProject project = null; >+ try >+ { >+ // create the common project and create an interface >+ project = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB"}, "","1.5"); >+ createFile("/P/Sub.java", >+ "abstract class Sup<C> {\n" + >+ " protected void m(C classifier) {}\n"+ >+ " public void use(C owner) { m (owner); }\n" + >+ "}\n" + >+ "public class Sub extends Sup<String>{\n" + >+ " @Override\n"+ >+ " protected void m(String classifier) {}\n"+ >+ " protected void m(Sub classifier) {}\n"+ >+ "}\n" ); >+ // search >+ SearchPattern pattern = SearchPattern.createPattern("Sub.m(Sub)", METHOD, REFERENCES, EXACT_RULE); >+ search(pattern, SearchEngine.createWorkspaceScope(), this.resultCollector); >+ assertSearchResults(""); >+ >+ } finally { >+ deleteProject(project); >+ } >+ } >+ >+ /** >+ * @bug 342393: Anonymous class' occurrence count is incorrect when two methods in a class have the same name. >+ * @test Search for Enumerators with anonymous types >+ * >+ * @throws CoreException >+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=342393" >+ */ >+ public void testBug342393() throws CoreException { >+ try { >+ IJavaProject project = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB"}, "bin", "1.5"); >+ String content = "package b342393;\n" + "class Generic {\n" >+ + "enum A {\n" + "ONE {\n" + "A getSquare() {\n" >+ + "return ONE;\n" + "}\n" + "},\n" + "TWO {\n" >+ + "A getSquare() {\n" + "return TWO;\n" + "}\n" + "};\n" >+ + "abstract A getSquare();\n" + "}\n" + "}"; >+ createFolder("/P/b342393"); >+ createFile("/P/b342393/Generic.java", content); >+ IJavaSearchScope scope = SearchEngine. createJavaSearchScope( >+ new IJavaElement[] { project }, IJavaSearchScope.SOURCES); >+ search("getSquare", METHOD, DECLARATIONS, EXACT_RULE, scope, this.resultCollector); >+ assertSearchResults("b342393/Generic.java A b342393.Generic$A.ONE:<anonymous>#1.getSquare() [getSquare] EXACT_MATCH\n" + >+ "b342393/Generic.java A b342393.Generic$A.TWO:<anonymous>#1.getSquare() [getSquare] EXACT_MATCH\n" + >+ "b342393/Generic.java A b342393.Generic$A.getSquare() [getSquare] EXACT_MATCH"); >+ } finally { >+ deleteProject("P"); >+ } >+ } >+} >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchScopeTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchScopeTests.java >index deb70fd..52af315 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchScopeTests.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchScopeTests.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2008 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -1025,7 +1025,7 @@ > > // Index the output location as it is a library for the project > IndexManager indexManager = JavaModelManager.getIndexManager(); >- indexManager.indexLibrary(new Path("/P1/bin"), project.getProject()); >+ indexManager.indexLibrary(new Path("/P1/bin"), project.getProject(), null); > waitUntilIndexesReady(); > > // Search for all types >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchTests.java >index 923d153..316b1c7 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchTests.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchTests.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -2168,8 +2168,8 @@ > search("MissingFieldType.*", FIELD, DECLARATIONS, getJavaSearchScope()); > assertSearchResults( > "AbortCompilation.jar AbortCompilation.MissingFieldType.field [No source] EXACT_MATCH\n" + >- "AbortCompilation.jar AbortCompilation.MissingFieldType.otherField [No source] EXACT_MATCH\n" + >- "AbortCompilation.jar AbortCompilation.MissingFieldType.missing [No source] POTENTIAL_MATCH" >+ "AbortCompilation.jar AbortCompilation.MissingFieldType.missing [No source] EXACT_MATCH\n" + >+ "AbortCompilation.jar AbortCompilation.MissingFieldType.otherField [No source] EXACT_MATCH" > ); > } finally { > // reset classpath >@@ -2229,8 +2229,8 @@ > search("MissingArgumentType.foo*", METHOD, DECLARATIONS, getJavaSearchScope()); > assertSearchResults( > "AbortCompilation.jar void AbortCompilation.MissingArgumentType.foo() [No source] EXACT_MATCH\n" + >- "AbortCompilation.jar void AbortCompilation.MissingArgumentType.foo2() [No source] EXACT_MATCH\n" + >- "AbortCompilation.jar void AbortCompilation.MissingArgumentType.foo(java.util.EventListener) [No source] POTENTIAL_MATCH" >+ "AbortCompilation.jar void AbortCompilation.MissingArgumentType.foo(java.util.EventListener) [No source] EXACT_MATCH\n" + >+ "AbortCompilation.jar void AbortCompilation.MissingArgumentType.foo2() [No source] EXACT_MATCH" > ); > } finally { > // reset classpath >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NullAnnotationModelTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NullAnnotationModelTests.java >new file mode 100644 >index 0000000..82e5422 >--- /dev/null >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NullAnnotationModelTests.java >@@ -0,0 +1,489 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 GK Software AG 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: >+ * Stephan Herrmann - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.core.tests.model; >+ >+import java.io.File; >+import java.io.IOException; >+import java.io.ByteArrayInputStream; >+import java.net.URL; >+import java.util.Hashtable; >+import java.util.List; >+ >+import junit.framework.Test; >+ >+import org.eclipse.core.resources.IFile; >+import org.eclipse.core.resources.IMarker; >+import org.eclipse.core.resources.IResource; >+import org.eclipse.core.resources.IncrementalProjectBuilder; >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.core.runtime.FileLocator; >+import org.eclipse.core.runtime.Platform; >+import org.eclipse.jdt.core.ICompilationUnit; >+import org.eclipse.jdt.core.IJavaModelMarker; >+import org.eclipse.jdt.core.IJavaProject; >+import org.eclipse.jdt.core.JavaCore; >+import org.eclipse.jdt.core.compiler.IProblem; >+import org.eclipse.jdt.core.dom.AST; >+import org.eclipse.jdt.core.dom.ASTParser; >+import org.eclipse.jdt.core.dom.CompilationUnit; >+import org.eclipse.jdt.core.dom.MarkerAnnotation; >+import org.eclipse.jdt.core.dom.MethodDeclaration; >+import org.eclipse.jdt.core.dom.Modifier; >+import org.eclipse.jdt.core.dom.SingleVariableDeclaration; >+import org.eclipse.jdt.core.dom.TypeDeclaration; >+ >+public class NullAnnotationModelTests extends ReconcilerTests { >+ >+ String ANNOTATION_LIB; >+ >+ public static Test suite() { >+ return buildModelTestSuite(NullAnnotationModelTests.class); >+ } >+ >+ public NullAnnotationModelTests(String name) { >+ super(name); >+ } >+ >+ static { >+// TESTS_NAMES = new String[] { "testMissingAnnotation5" }; >+ } >+ >+ public void setUp() throws Exception { >+ super.setUp(); >+ File bundleFile = FileLocator.getBundleFile(Platform.getBundle("org.eclipse.jdt.annotation")); >+ this.ANNOTATION_LIB = bundleFile.isDirectory() ? bundleFile.getPath()+"/bin" : bundleFile.getPath(); >+ } >+ >+ protected String testJarPath(String jarName) throws IOException { >+ URL libEntry = Platform.getBundle("org.eclipse.jdt.core.tests.model").getEntry("/workspace/NullAnnotations/lib/"+jarName); >+ return FileLocator.toFileURL(libEntry).getPath(); >+ } >+ >+ // DISABLED due to dysfunctional global default after Bug 366063 - Compiler should not add synthetic @NonNull annotations >+ public void _testConvertedSourceType1() throws CoreException, InterruptedException { >+ try { >+ // Resources creation >+ IJavaProject p = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB", this.ANNOTATION_LIB}, "bin", "1.5"); >+ p.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED); >+ p.setOption(JavaCore.COMPILER_NONNULL_IS_DEFAULT, JavaCore.ENABLED); >+ >+ this.createFolder("/P/p1"); >+ String c1SourceString = >+ "package p1;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class C1 {\n" + >+ " public String foo(@Nullable Object arg) {\n" + // this is consumed via SourceTypeConverter >+ " return arg == null ? \"\" : arg.toString();\n" + >+ " }\n" + >+ "}\n"; >+ this.createFile( >+ "/P/p1/C1.java", >+ c1SourceString); >+ >+ this.createFolder("/P/p2"); >+ String c2SourceString = >+ "package p2;\n" + >+ "public class C2 {\n" + >+ " String bar(p1.C1 c, C2 c2) {;\n" + >+ " return c.foo(null);\n" + // don't complain despite default nonnull, foo has explicit @Nullable >+ " }\n" + >+ " String foo(Object arg) {\n" + >+ " return arg == null ? null : arg.toString();\n" + >+ " }\n" + >+ "}\n"; >+ this.createFile( >+ "/P/p2/C2.java", >+ c2SourceString); >+ >+ char[] c2SourceChars = c2SourceString.toCharArray(); >+ this.problemRequestor.initialize(c2SourceChars); >+ >+ getCompilationUnit("/P/p2/C2.java").getWorkingCopy(this.wcOwner, null); >+ >+ assertProblems("Unexpected problems", "----------\n" + >+ "1. WARNING in /P/p2/C2.java (at line 7)\n" + >+ " return arg == null ? null : arg.toString();\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Potential type mismatch: required \'@NonNull String\' but nullness of the provided value is unknown\n" + >+ "----------\n"); >+ } finally { >+ deleteProject("P"); >+ } >+ } >+ >+ // DISABLED due to dysfunctional global default after Bug 366063 - Compiler should not add synthetic @NonNull annotations >+ public void _testBinaryType1() throws CoreException, InterruptedException, IOException { >+ try { >+ // Resources creation >+ IJavaProject p = createJavaProject("P", new String[] {""}, >+ new String[] {"JCL15_LIB", this.ANNOTATION_LIB, testJarPath("example.jar")}, >+ "bin", "1.5"); >+ p.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED); >+ p.setOption(JavaCore.COMPILER_NONNULL_IS_DEFAULT, JavaCore.ENABLED); >+ >+ // example.jar contains p1/C1.java just like testConvertedSourceType1() >+ >+ this.createFolder("/P/p2"); >+ String c2SourceString = >+ "package p2;\n" + >+ "public class C2 {\n" + >+ " String bar(p1.C1 c) {;\n" + >+ " return c.foo(null);\n" + // don't complain despite default nonnull, foo has explicit @Nullable >+ " }\n" + >+ " String foo(Object arg) {\n" + >+ " return arg == null ? null : arg.toString();\n" + >+ " }\n" + >+ "}\n"; >+ this.createFile( >+ "/P/p2/C2.java", >+ c2SourceString); >+ >+ char[] c2SourceChars = c2SourceString.toCharArray(); >+ this.problemRequestor.initialize(c2SourceChars); >+ >+ getCompilationUnit("/P/p2/C2.java").getWorkingCopy(this.wcOwner, null); >+ >+ assertProblems("Unexpected problems", "----------\n" + >+ "1. WARNING in /P/p2/C2.java (at line 7)\n" + >+ " return arg == null ? null : arg.toString();\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Potential type mismatch: required \'@NonNull String\' but nullness of the provided value is unknown\n" + >+ "----------\n"); >+ } finally { >+ deleteProject("P"); >+ } >+ } >+ >+ // DISABLED: no longer a problem since bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults >+ public void _testMissingAnnotation1() throws CoreException { >+ try { >+ // Resources creation >+ IJavaProject p = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB", this.ANNOTATION_LIB}, "bin", "1.5"); >+ p.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED); >+ p.setOption(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, "in.valid"); >+ >+ this.createFolder("/P/p1"); >+ String c1SourceString = >+ "package p1;\n" + >+ "@org.eclipse.jdt.annotation.NonNullByDefault\n" + >+ "public class C1 {\n" + >+ " public String foo(Object arg) {\n" + >+ " return arg == null ? \"\" : arg.toString();\n" + >+ " }\n" + >+ "}\n"; >+ this.createFile( >+ "/P/p1/C1.java", >+ c1SourceString); >+ >+ this.problemRequestor.initialize(c1SourceString.toCharArray()); >+ >+ getCompilationUnit("/P/p1/C1.java").getWorkingCopy(this.wcOwner, null); >+ >+ assertProblems("Unexpected problems", >+ "----------\n" + >+ "1. ERROR in /P/p1/C1.java (at line 1)\n" + >+ " package p1;\n" + >+ " ^\n" + >+ "Buildpath problem: the type in.valid, which is configured as a null annotation type, cannot be resolved\n" + >+ "----------\n"); >+ } finally { >+ deleteProject("P"); >+ } >+ } >+ >+ // DISABLED: no longer a problem since bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults >+ public void _testMissingAnnotation2() throws CoreException { >+ Hashtable javaOptions = JavaCore.getOptions(); >+ try { >+ // Resources creation >+ IJavaProject p = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB", this.ANNOTATION_LIB}, "bin", "1.5"); >+ IFile settings = (IFile) p.getProject().findMember(".settings/org.eclipse.jdt.core.prefs"); >+ settings.appendContents(new ByteArrayInputStream("\norg.eclipse.jdt.core.compiler.annotation.nonnull=not.valid\n".getBytes()), 0, null); >+ p.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED); >+ >+ this.createFolder("/P/p1"); >+ String c1SourceString = >+ "package p1;\n" + >+ "@org.eclipse.jdt.annotation.NonNullByDefault\n" + >+ "public class C1 {\n" + >+ " public String foo(Object arg) {\n" + >+ " return arg == null ? \"\" : arg.toString();\n" + >+ " }\n" + >+ "}\n"; >+ this.createFile( >+ "/P/p1/C1.java", >+ c1SourceString); >+ >+ this.problemRequestor.initialize(c1SourceString.toCharArray()); >+ >+ getCompilationUnit("/P/p1/C1.java").getWorkingCopy(this.wcOwner, null); >+ >+ assertProblems("Unexpected problems", >+ "----------\n" + >+ "1. ERROR in /P/p1/C1.java (at line 1)\n" + >+ " package p1;\n" + >+ " ^\n" + >+ "Buildpath problem: the type not.valid, which is configured as a null annotation type, cannot be resolved\n" + >+ "----------\n"); >+ } finally { >+ deleteProject("P"); >+ JavaCore.setOptions(javaOptions); >+ // work against side-effect of JavaRuntime listening to change of prefs-file. >+ // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=302850#c25 >+ } >+ } >+ >+ // Bug 363858 - [dom] early throwing of AbortCompilation causes NPE in CompilationUnitResolver >+ // currently not actually challenging the NPE, because we no longer report >+ // "Cannot use the unqualified name \'invalid\' as an annotation name for null specification" >+ // DISABLED: no longer a problem since bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults >+ public void _testMissingAnnotation3() throws CoreException { >+ try { >+ // Resources creation >+ IJavaProject p = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB", this.ANNOTATION_LIB}, "bin", "1.5"); >+ p.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED); >+ p.setOption(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, "invalid"); >+ >+ this.createFolder("/P/p1"); >+ String c1SourceString = >+ "package p1;\n" + >+ "@org.eclipse.jdt.annotation.NonNullByDefault\n" + >+ "public class C1 {\n" + >+ " public String foo(Object arg) {\n" + >+ " return arg == null ? \"\" : arg.toString();\n" + >+ " }\n" + >+ "}\n"; >+ this.createFile( >+ "/P/p1/C1.java", >+ c1SourceString); >+ >+ this.problemRequestor.initialize(c1SourceString.toCharArray()); >+ >+ final ICompilationUnit unit = getCompilationUnit("/P/p1/C1.java").getWorkingCopy(this.wcOwner, null); >+ assertProblems("Unexpected problems", >+ "----------\n" + >+ "1. ERROR in /P/p1/C1.java (at line 1)\n" + >+ " package p1;\n" + >+ " ^\n" + >+ "Buildpath problem: the type invalid, which is configured as a null annotation type, cannot be resolved\n" + >+ "----------\n"); >+ >+ ASTParser parser = ASTParser.newParser(AST.JLS4); >+ parser.setProject(p); >+ parser.setResolveBindings(true); >+ parser.setSource(unit); >+ CompilationUnit ast = (CompilationUnit) parser.createAST(null); >+ assertNotNull("ast should not be null", ast); >+ this.problemRequestor.reset(); >+ this.problemRequestor.beginReporting(); >+ IProblem[] problems = ast.getProblems(); >+ for (int i=0; i<problems.length; i++) >+ this.problemRequestor.acceptProblem(problems[i]); >+ assertProblems("Unexpected problems (2)", >+ "----------\n" + >+ "1. ERROR in /P/p1/C1.java (at line 1)\n" + >+ " package p1;\n" + >+ " ^\n" + >+ "Buildpath problem: the type invalid, which is configured as a null annotation type, cannot be resolved\n" + >+ "----------\n"); >+ } finally { >+ deleteProject("P"); >+ } >+ } >+ >+ // initialization of null annotations is triggered from package-info.java: illegal simple name >+ public void testMissingAnnotation4() throws CoreException, InterruptedException { >+ try { >+ // Resources creation >+ IJavaProject p = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB", this.ANNOTATION_LIB}, "bin", "1.5"); >+ p.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED); >+ p.setOption(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, "invalid"); >+ >+ this.createFolder("/P/p1"); >+ String piSourceString = >+ "@org.eclipse.jdt.annotation.NonNullByDefault\n" + >+ "package p1;\n"; >+ this.createFile( >+ "/P/p1/package-info.java", >+ piSourceString); >+ >+ this.problemRequestor.initialize(piSourceString.toCharArray()); >+ >+ // Challenge CompilationUnitProblemFinder: >+ final ICompilationUnit unit = getCompilationUnit("/P/p1/package-info.java").getWorkingCopy(this.wcOwner, null); >+// This error is not raised currently: >+// String expectedError = "----------\n" + >+// "1. ERROR in /P/p1/package-info.java (at line 0)\n" + >+// " @org.eclipse.jdt.annotation.NonNullByDefault\n" + >+// " ^\n" + >+// "Cannot use the unqualified name \'invalid\' as an annotation name for null specification\n" + >+// "----------\n"; >+// assertProblems("Unexpected problems from CompilationUnitProblemFinder", expectedError); >+ assertNoProblem(unit.getBuffer().getCharacters(), unit); >+ >+ // Challenge JavaBuilder: >+ p.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); >+ IMarker[] markers = p.getProject().findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE); >+// assertMarkers("Unexpected markers", >+// "Cannot use the unqualified name 'invalid' as an annotation name for null specification", >+// markers); >+// assertEquals("Unexpected marker path", "/P", markers[0].getResource().getFullPath().toString()); >+ assertEquals("Should have no markers", 0, markers.length); >+ >+ // Challenge CompilationUnitResolver: >+ ASTParser parser = ASTParser.newParser(AST.JLS4); >+ parser.setProject(p); >+ parser.setResolveBindings(true); >+ parser.setSource(unit); >+ CompilationUnit ast = (CompilationUnit) parser.createAST(null); >+ assertNotNull("ast should not be null", ast); >+// this.problemRequestor.reset(); >+// this.problemRequestor.beginReporting(); >+// IProblem[] problems = ast.getProblems(); >+// for (int i=0; i<problems.length; i++) >+// this.problemRequestor.acceptProblem(problems[i]); >+// assertProblems("Unexpected problems from CompilationUnitResolver", expectedError); >+ assertEquals("Should have no problems", 0, ast.getProblems().length); >+ } finally { >+ deleteProject("P"); >+ } >+ } >+ >+ // initialization of null annotations is >+ // - triggered from resolveTypesFor(MethodBinding) >+ // - default is defined in package-info.java: >+ // must detect missing non-null annotation and report against the project >+ // DISABLED: no longer a problem since bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults >+ public void _testMissingAnnotation5() throws CoreException, InterruptedException { >+ try { >+ // Resources creation >+ IJavaProject p = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB", this.ANNOTATION_LIB}, "bin", "1.5"); >+ p.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED); >+ p.setOption(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, "pack.Missing"); >+ >+ this.createFolder("/P/p1"); >+ String piSourceString = >+ "@org.eclipse.jdt.annotation.NonNullByDefault\n" + >+ "package p1;\n"; >+ this.createFile("/P/p1/package-info.java", piSourceString); >+ >+ String c1SourceString = >+ "package p1;\n" + >+ "public class C1 {\n" + >+ " String foo(String arg) { return arg; }\n" + >+ "}\n"; >+ this.createFile("/P/p1/C1.java", c1SourceString); >+ >+ this.problemRequestor.initialize(piSourceString.toCharArray()); >+ >+ // Challenge CompilationUnitProblemFinder: >+ assertNoProblem(piSourceString.toCharArray(), getCompilationUnit("/P/p1/package-info.java")); >+ >+ this.problemRequestor.initialize(c1SourceString.toCharArray()); >+ >+ // Challenge CompilationUnitProblemFinder: >+ ICompilationUnit unit = getCompilationUnit("/P/p1/C1.java").getWorkingCopy(this.wcOwner, null); >+ String expectedError = "----------\n" + >+ "1. ERROR in /P/p1/C1.java (at line 1)\n" + >+ " package p1;\n" + >+ " ^\n" + >+ "Buildpath problem: the type pack.Missing, which is configured as a null annotation type, cannot be resolved\n" + >+ "----------\n"; >+ assertProblems("Unexpected problems", expectedError); >+ >+ // Challenge JavaBuilder: >+ p.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); >+ IMarker[] markers = p.getProject().findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE); >+ assertMarkers("Unexpected markers", >+ "Buildpath problem: the type pack.Missing, which is configured as a null annotation type, cannot be resolved", >+ markers); >+// toggle expectation depending on how CAT_BUILDPATH problems are reported (see AbstractImageBuilder.storeProblemsFor(..)) >+// assertEquals("Unexpected marker path", "/P", markers[0].getResource().getFullPath().toString()); >+ assertEquals("Unexpected marker path", "/P/p1/C1.java", markers[0].getResource().getFullPath().toString()); >+ >+ // Challenge CompilationUnitResolver: >+ ASTParser parser = ASTParser.newParser(AST.JLS4); >+ parser.setProject(p); >+ parser.setResolveBindings(true); >+ parser.setSource(unit); >+ CompilationUnit ast = (CompilationUnit) parser.createAST(null); >+ assertNotNull("ast should not be null", ast); >+ this.problemRequestor.reset(); >+ this.problemRequestor.beginReporting(); >+ IProblem[] problems = ast.getProblems(); >+ for (int i=0; i<problems.length; i++) >+ this.problemRequestor.acceptProblem(problems[i]); >+ assertProblems("Unexpected problems (2)", expectedError); >+ } finally { >+ deleteProject("P"); >+ } >+ } >+ >+ // A synthetic annotation from a default should not be converted to DOM AST >+ public void testAnnotationAST1() throws CoreException, InterruptedException { >+ try { >+ // Resources creation >+ IJavaProject p = createJavaProject("P", new String[] {""}, new String[] {"JCL15_LIB", this.ANNOTATION_LIB}, "bin", "1.5"); >+ p.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED); >+ >+ this.createFolder("/P/p1"); >+ // bug could only be triggered if ASTConvert actually finds a '@' >+ // so in addition to the synthetic annotation there must also be a real one: >+ String annotSourceString = >+ "package p1;\n" + >+ "import java.lang.annotation.ElementType;\n" + >+ "import java.lang.annotation.Target;\n" + >+ "@Target({ElementType.PARAMETER,ElementType.METHOD})\n" + >+ "public @interface Annot {}\n"; >+ this.createFile( >+ "/P/p1/Annot.java", >+ annotSourceString); >+ String c1SourceString = >+ "package p1;\n" + >+ "@org.eclipse.jdt.annotation.NonNullByDefault\n" + >+ "public class C1 {\n" + >+ " public @Annot Object foo(@Annot Object arg) {\n" + >+ " return this;\n" + >+ " }\n" + >+ "}\n"; >+ this.createFile( >+ "/P/p1/C1.java", >+ c1SourceString); >+ >+ this.problemRequestor.initialize(c1SourceString.toCharArray()); >+ >+ final ICompilationUnit unit = getCompilationUnit("/P/p1/C1.java").getWorkingCopy(this.wcOwner, null); >+ assertNoProblem(c1SourceString.toCharArray(), unit); >+ >+ ASTParser parser = ASTParser.newParser(AST.JLS4); >+ parser.setProject(p); >+ parser.setResolveBindings(true); >+ parser.setSource(unit); >+ CompilationUnit ast = (CompilationUnit) parser.createAST(null); >+ assertNotNull("ast should not be null", ast); >+ TypeDeclaration type = (TypeDeclaration) ast.types().get(0); >+ assertNotNull("type should not be null", type); >+ MethodDeclaration method = (MethodDeclaration) type.bodyDeclarations().get(0); >+ assertNotNull("method should not be null", method); >+ SingleVariableDeclaration arg = (SingleVariableDeclaration) method.parameters().get(0); >+ assertNotNull("argument should not be null", arg); >+ List modifiers = arg.modifiers(); >+ assertEquals("Should have exactly one modifier", 1, modifiers.size()); >+ assertEquals("Unexpected modifier", "@Annot", ((MarkerAnnotation)modifiers.get(0)).toString()); >+ modifiers = method.modifiers(); >+ assertEquals("Method should have exactly two modifiers", 2, modifiers.size()); >+ assertEquals("Unexpected modifier #1 for method", "public", ((Modifier)modifiers.get(0)).toString()); >+ assertEquals("Unexpected modifier #2 for method", "@Annot", ((MarkerAnnotation)modifiers.get(1)).toString()); >+ } finally { >+ deleteProject("P"); >+ } >+ } >+} >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RenameTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RenameTests.java >index f08ed7a..92b80fa 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RenameTests.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RenameTests.java >@@ -115,9 +115,9 @@ > assertTrue("moved from handle should be original", destDelta.getMovedFromElement().equals(e.getParent())); > } else { > assertTrue("Destination container not changed", destDelta != null && deltaChildrenChanged(destDelta)); >- IJavaElementDelta[] deltas = destDelta.getAddedChildren(); >+ IJavaElementDelta[] deltas = force ? destDelta.getChangedChildren() : destDelta.getAddedChildren(); > assertTrue("Added children not correct for element rename", deltas.length > i && deltas[i].getElement().equals(renamed)); >- assertTrue("kind should be K_ADDED", deltas[i].getKind() == IJavaElementDelta.ADDED); >+ assertTrue("kind should be K_ADDED", deltas[i].getKind() == (force? IJavaElementDelta.CHANGED : IJavaElementDelta.ADDED)); > deltas = destDelta.getRemovedChildren(); > assertTrue("Removed children not correct for element rename", deltas.length > i && deltas[i].getElement().equals(e)); > assertTrue("kind should be K_REMOVED", deltas[i].getKind() == IJavaElementDelta.REMOVED); >@@ -364,11 +364,12 @@ > > assertDeltas( > "Unexpected deltas", >- "P[*]: {CHILDREN}\n" + >- " src[*]: {CHILDREN}\n" + >- " <default>[*]: {CHILDREN}\n" + >- " X.java[-]: {MOVED_TO(Y.java [in <default> [in src [in P]]])}\n" + >- " Y.java[+]: {MOVED_FROM(X.java [in <default> [in src [in P]]])}" >+ "P[*]: {CHILDREN}\n" + >+ " src[*]: {CHILDREN}\n" + >+ " <default>[*]: {CHILDREN}\n" + >+ " X.java[-]: {MOVED_TO(Y.java [in <default> [in src [in P]]])}\n" + >+ " Y.java[*]: {CHILDREN | FINE GRAINED | PRIMARY RESOURCE}\n" + >+ " Y[+]: {MOVED_FROM(X [in X.java [in <default> [in src [in P]]]])}" > ); > } > /* >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests.java >index 429a4cb..73f1d9d 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -2686,4 +2686,43 @@ > ); > assertTrue("Not a parameter", ((ILocalVariable)elements[0]).isParameter()); > } >+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=244544 >+public void testConstantInLocal() throws JavaModelException { >+ this.workingCopies = new ICompilationUnit[2]; >+ this.workingCopies[0] = getWorkingCopy( >+ "/Resolve/src/Test2.java", >+ "class X {\n" + >+ " public static void main(String[] args) {\n" + >+ " class Local {\n" + >+ " private static final long CONSTANT = 1L; // code select fails\n" + >+ " }\n" + >+ " new X() {\n" + >+ " private static final long FINAL = 1L; // code select fails\n" + >+ " };\n" + >+ " }\n" + >+ "}\n"); >+ >+ String str = this.workingCopies[0].getSource(); >+ String selectAt = "FINAL"; >+ String selection = "FINAL"; >+ int start = str.indexOf(selectAt); >+ int length = selection.length(); >+ IJavaElement[] elements = this.workingCopies[0].codeSelect(start, length, this.wcOwner); >+ >+ assertElementsEqual( >+ "Unexpected elements", >+ "FINAL [in <anonymous #1> [in main(String[]) [in X [in [Working copy] Test2.java [in <default> [in src [in Resolve]]]]]]]", >+ elements); >+ >+ selectAt = "CONSTANT"; >+ selection = "CONSTANT"; >+ start = str.indexOf(selectAt); >+ length = selection.length(); >+ elements = this.workingCopies[0].codeSelect(start, length, this.wcOwner); >+ >+ assertElementsEqual( >+ "Unexpected elements", >+ "CONSTANT [in Local [in main(String[]) [in X [in [Working copy] Test2.java [in <default> [in src [in Resolve]]]]]]]", >+ elements); >+} > } >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests2.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests2.java >index 91034b6..4126938 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests2.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests2.java >@@ -1203,4 +1203,48 @@ > this.deleteProject("P1"); > } > } >+public void testBug356325() throws Exception{ >+ try { >+ // create P1 >+ this.createJavaProject( >+ "P1", >+ new String[]{"src"}, >+ new String[]{"JCL15_LIB"}, >+ "bin", >+ "1.5"); >+ >+ this.createFolder("/P1/src/p"); >+ this.createFile("/P1/src/p/C.java", >+ "package p;" + >+ "\n" + >+ "public class C {\n" + >+ " public void m() {\n" + >+ " class Inner<T> {\n" + >+ " Inner() {\n"+ >+ " }\n"+ >+ " Inner<String> i = new Inner<String>();\n"+ >+ " }\n" + >+ "}\n"); >+ >+ waitUntilIndexesReady(); >+ >+ // do code select >+ ICompilationUnit cu= getCompilationUnit("P1", "src", "p", "C.java"); >+ >+ String str = cu.getSource(); >+ >+ String selection = "Inner"; >+ int start = str.lastIndexOf(selection); >+ int length = selection.length(); >+ IJavaElement[] elements = cu.codeSelect(start, length); >+ >+ assertElementsEqual( >+ "Unexpected elements", >+ "Inner() [in Inner [in m() [in C [in C.java [in p [in src [in P1]]]]]]]", >+ elements >+ ); >+ } finally { >+ this.deleteProject("P1"); >+ } >+} > } >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunJavaSearchGenericTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunJavaSearchGenericTests.java >index d33e9c5..0a06040 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunJavaSearchGenericTests.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunJavaSearchGenericTests.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2006 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -45,6 +45,7 @@ > AbstractJavaSearchTests.JAVA_SEARCH_SUITES = new ArrayList(Arrays.asList(getJavaSearchTestClasses())); > List allClasses = new ArrayList(AbstractJavaSearchTests.JAVA_SEARCH_SUITES); > allClasses.add(JavaSearchBugsTests.class); >+ allClasses.add(JavaSearchBugsTests2.class); > > // Reset forgotten subsets of tests > TestCase.TESTS_PREFIX = null; >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunJavaSearchTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunJavaSearchTests.java >index 8917c29..36977b7 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunJavaSearchTests.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunJavaSearchTests.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -58,10 +58,12 @@ > // Get all classes > List allClasses = new ArrayList(TEST_CLASSES); > allClasses.add(JavaSearchBugsTests.class); >+ allClasses.add(JavaSearchBugsTests2.class); > allClasses.add(JavaSearchMultipleProjectsTests.class); > allClasses.add(SearchTests.class); > allClasses.add(JavaSearchScopeTests.class); > allClasses.add(MatchingRegionsTest.class); >+ allClasses.add(JavaIndexTests.class); > > // Reset forgotten subsets of tests > TestCase.TESTS_PREFIX = null; >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/TypeResolveTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/TypeResolveTests.java >index 4bb846e..6625053 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/TypeResolveTests.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/TypeResolveTests.java >@@ -33,6 +33,7 @@ > import org.eclipse.jdt.core.JavaModelException; > import org.eclipse.jdt.core.tests.util.Util; > import org.eclipse.jdt.internal.core.LocalVariable; >+import org.eclipse.jdt.internal.core.SourceType; > > public class TypeResolveTests extends ModifyingResourceTests { > ICompilationUnit cu; >@@ -700,4 +701,107 @@ > deleteProject("P"); > } > } >+/** >+ * @bug 342393: Anonymous class' occurrence count is incorrect when two methods in a class have the same name. >+ * >+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=342393" >+ */ >+public void testBug342393() throws Exception { >+ try { >+ IJavaProject project = createJavaProject("Test342393", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin", "1.5"); >+ project.open(null); >+ String fileContent = "package p;\n" >+ + "public class Test {\n" >+ + "Test() {\n" >+ + " class A {\n" >+ + " // one \n" >+ + " public void foo() {\n" >+ + " Throwable a1 = new Throwable(){ // two \n" >+ + " };\n" >+ + " Throwable b1 = new Throwable(){ // three \n" >+ + " };\n" >+ + " }\n" >+ + " public void bar() {\n" >+ + " Throwable b2 = new Throwable(){ // four\n" >+ + " Throwable bi2 = new Throwable() { // five\n" >+ + " };\n" >+ + " };\n" >+ + " }\n" >+ + " class B {\n" >+ + " Throwable t1 = new Throwable() { // six\n" >+ + " };\n" >+ + " Throwable t2 = new Throwable() { // seven\n" >+ + " };\n" >+ + " }\n" >+ + " };\n" >+ + " {\n" >+ + " Throwable a3 = new Throwable(){ // eight\n" >+ + " Throwable ai3 = new Throwable() { // nine\n" >+ + " };\n" >+ + " };\n" >+ + " }\n" >+ + "}\n" >+ + "public static void main(String[] args) throws Exception {\n" >+ + " Throwable c1 = new Throwable() { // ten\n" >+ + " };\n" >+ + " Throwable c2 = new Throwable() { // eleven\n" >+ + " };\n" >+ + "}\n" >+ + "}\n"; >+ createFolder("/Test342393/src/p"); >+ createFile( "/Test342393/src/p/Test.java", fileContent); >+ >+ ICompilationUnit unit = getCompilationUnit("/Test342393/src/p/Test.java"); >+ int index = fileContent.indexOf("// one"); >+ IJavaElement element = unit.getElementAt(index); >+ assertEquals("Incorrect Type selected", "p.Test$A", ((SourceType)element.getParent()).getFullyQualifiedName()); >+ index = fileContent.indexOf("// two"); >+ element = unit.getElementAt(index); >+ assertEquals("Incorrect Type selected", "p.Test$A$1", ((SourceType)element).getFullyQualifiedName()); >+ index = fileContent.indexOf("// three"); >+ element = unit.getElementAt(index); >+ assertEquals("Incorrect Type selected", "p.Test$A$2", ((SourceType)element).getFullyQualifiedName()); >+ index = fileContent.indexOf("// four"); >+ element = unit.getElementAt(index); >+ assertEquals("Incorrect Type selected", "p.Test$A$3", ((SourceType)element).getFullyQualifiedName()); >+ index = fileContent.indexOf("// five"); >+ element = unit.getElementAt(index); >+ assertEquals("Incorrect Type selected", "p.Test$A$3$1", ((SourceType)element).getFullyQualifiedName()); >+ index = fileContent.indexOf("// six"); >+ element = unit.getElementAt(index); >+ assertEquals("Incorrect Type selected", "p.Test$A$B$1", ((SourceType)element).getFullyQualifiedName()); >+ index = fileContent.indexOf("// seven"); >+ element = unit.getElementAt(index); >+ assertEquals("Incorrect Type selected", "p.Test$A$B$2", ((SourceType)element).getFullyQualifiedName()); >+ >+ String handleId = ((SourceType)element).getHandleMemento(); >+ IJavaElement newElement = JavaCore.create(handleId); >+ assertEquals("Incorrect Element", element, newElement); >+ >+ index = fileContent.indexOf("// eight"); >+ element = unit.getElementAt(index); >+ assertEquals("Incorrect Type selected", "p.Test$1", ((SourceType)element).getFullyQualifiedName()); >+ index = fileContent.indexOf("// nine"); >+ element = unit.getElementAt(index); >+ assertEquals("Incorrect Type selected", "p.Test$1$1", ((SourceType)element).getFullyQualifiedName()); >+ >+ handleId = ((SourceType)element).getHandleMemento(); >+ newElement = JavaCore.create(handleId); >+ assertEquals("Incorrect Element", element, newElement); >+ >+ index = fileContent.indexOf("// ten"); >+ element = unit.getElementAt(index); >+ assertEquals("Incorrect Type selected", "p.Test$2", ((SourceType)element).getFullyQualifiedName()); >+ index = fileContent.indexOf("// eleven"); >+ element = unit.getElementAt(index); >+ assertEquals("Incorrect Type selected", "p.Test$3", ((SourceType)element).getFullyQualifiedName()); >+ >+ handleId = ((SourceType)element).getHandleMemento(); >+ newElement = JavaCore.create(handleId); >+ assertEquals("Incorrect Element", element, newElement); >+ } >+ finally { >+ deleteProject("Test342393"); >+ } >+} > } >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/WorkingCopyTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/WorkingCopyTests.java >index f23e3ca..8849aff 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/WorkingCopyTests.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/WorkingCopyTests.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -202,8 +202,9 @@ > > /** > * Test creating a working copy on a class file with a customized buffer. >+ * As of https://bugs.eclipse.org/337935 this test is no longer valid. > */ >-public void testOnClassFile() throws JavaModelException, IOException { >+public void _testOnClassFile() throws JavaModelException, IOException { > // ensure the external JCL is copied > setupExternalJCL("jclMin"); > >diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingStatementsTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingStatementsTest.java >index 5ea8bc1..429dce8 100644 >--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingStatementsTest.java >+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingStatementsTest.java >@@ -15,6 +15,7 @@ > import junit.framework.TestSuite; > > import org.eclipse.jdt.core.ICompilationUnit; >+import org.eclipse.jdt.core.IJavaProject; > import org.eclipse.jdt.core.IPackageFragment; > import org.eclipse.jdt.core.IPackageFragmentRoot; > import org.eclipse.jdt.core.JavaCore; >@@ -5694,7 +5695,157 @@ > assertEqualString(preview, buf.toString()); > > } >+ >+ >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=350285 >+ // Test that converting a multi catch into a normal catch using complete block copy doesn't change indentation >+ public void testTryStatementWithMultiCatch1() throws Exception { >+ createProject("P_17", JavaCore.VERSION_1_7); >+ IPackageFragmentRoot currentSourceFolder = getPackageFragmentRoot("P_17", "src"); >+ try { >+ IPackageFragment pack1= currentSourceFolder.createPackageFragment("test1", false, null); >+ StringBuffer buf= new StringBuffer(); >+ buf.append("package test1;\n"); >+ buf.append("public class E {\n"); >+ buf.append(" public void foo(int i) {\n"); >+ buf.append(" try {\n"); >+ buf.append(" System.out.println(\"foo\");\n"); >+ buf.append(" } catch (IllegalArgumentException | NullPointerException exe) {\n"); >+ buf.append(" System.out.println(exe);\n"); >+ buf.append(" }\n"); >+ buf.append(" }\n"); >+ buf.append("}\n"); >+ ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null); > >+ CompilationUnit astRoot= createAST(AST.JLS4, cu, false); >+ AST ast= astRoot.getAST(); >+ ASTRewrite rewrite= ASTRewrite.create(ast); >+ >+ assertTrue("Parse errors", (astRoot.getFlags() & ASTNode.MALFORMED) == 0); >+ TypeDeclaration type= findTypeDeclaration(astRoot, "E"); >+ MethodDeclaration methodDecl= findMethodDeclaration(type, "foo"); >+ Block block= methodDecl.getBody(); >+ List blockStatements= block.statements(); >+ assertTrue("Number of statements not 1", blockStatements.size() == 1); >+ { // convert multicatch to normal catch blocks >+ TryStatement tryStatement= (TryStatement) blockStatements.get(0); >+ List catchClauses= tryStatement.catchClauses(); >+ assertTrue("Number of catch clauses not 1", catchClauses.size() == 1); >+ CatchClause catchClause = (CatchClause) catchClauses.get(0); >+ >+ SingleVariableDeclaration singleVariableDeclaration= catchClause.getException(); >+ UnionType unionType = (UnionType) singleVariableDeclaration.getType(); >+ List types = unionType.types(); >+ assertTrue("Number of union types", types.size() == 2); >+ for (int i= types.size() - 1; i >= 0; i--) { >+ Type type2= (Type)types.get(i); >+ CatchClause newCatchClause= ast.newCatchClause(); >+ SingleVariableDeclaration newSingleVariableDeclaration= ast.newSingleVariableDeclaration(); >+ newSingleVariableDeclaration.setType((Type) rewrite.createCopyTarget(type2)); >+ newSingleVariableDeclaration.setName((SimpleName) rewrite.createCopyTarget(singleVariableDeclaration.getName())); >+ newCatchClause.setException(newSingleVariableDeclaration); >+ newCatchClause.setBody((Block) rewrite.createCopyTarget(catchClause.getBody())); >+ rewrite.getListRewrite(tryStatement, TryStatement.CATCH_CLAUSES_PROPERTY).insertAfter(newCatchClause, catchClause, null); >+ } >+ rewrite.remove(catchClause, null); >+ } >+ String preview= evaluateRewrite(cu, rewrite); >+ >+ buf= new StringBuffer(); >+ buf.append("package test1;\n"); >+ buf.append("public class E {\n"); >+ buf.append(" public void foo(int i) {\n"); >+ buf.append(" try {\n"); >+ buf.append(" System.out.println(\"foo\");\n"); >+ buf.append(" } catch (IllegalArgumentException exe) {\n"); >+ buf.append(" System.out.println(exe);\n"); >+ buf.append(" } catch (NullPointerException exe) {\n"); >+ buf.append(" System.out.println(exe);\n"); >+ buf.append(" }\n"); >+ buf.append(" }\n"); >+ buf.append("}\n"); >+ assertEqualString(preview, buf.toString()); >+ } finally { >+ deleteProject("P_17"); >+ } >+ } >+ >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=350285 >+ // similar to testTryStatementWithMultiCatch1() but has a different brace position >+ public void testTryStatementWithMultiCatch2() throws Exception { >+ IJavaProject project = createProject("P_17", JavaCore.VERSION_1_7); >+ project.setOption(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_BLOCK, DefaultCodeFormatterConstants.NEXT_LINE); >+ IPackageFragmentRoot currentSourceFolder = getPackageFragmentRoot("P_17", "src"); >+ try { >+ IPackageFragment pack1= currentSourceFolder.createPackageFragment("test1", false, null); >+ StringBuffer buf= new StringBuffer(); >+ buf.append("package test1;\n"); >+ buf.append("public class E {\n"); >+ buf.append(" public void foo(int i) {\n"); >+ buf.append(" try {\n"); >+ buf.append(" System.out.println(\"foo\");\n"); >+ buf.append(" } catch (IllegalArgumentException | NullPointerException exe)\n"); >+ buf.append(" {\n"); >+ buf.append(" System.out.println(exe);\n"); >+ buf.append(" }\n"); >+ buf.append(" }\n"); >+ buf.append("}\n"); >+ ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null); >+ >+ CompilationUnit astRoot= createAST(AST.JLS4, cu, false); >+ AST ast= astRoot.getAST(); >+ ASTRewrite rewrite= ASTRewrite.create(ast); >+ >+ assertTrue("Parse errors", (astRoot.getFlags() & ASTNode.MALFORMED) == 0); >+ TypeDeclaration type= findTypeDeclaration(astRoot, "E"); >+ MethodDeclaration methodDecl= findMethodDeclaration(type, "foo"); >+ Block block= methodDecl.getBody(); >+ List blockStatements= block.statements(); >+ assertTrue("Number of statements not 1", blockStatements.size() == 1); >+ { // convert multicatch to normal catch blocks >+ TryStatement tryStatement= (TryStatement) blockStatements.get(0); >+ List catchClauses= tryStatement.catchClauses(); >+ assertTrue("Number of catch clauses not 1", catchClauses.size() == 1); >+ CatchClause catchClause = (CatchClause) catchClauses.get(0); >+ >+ SingleVariableDeclaration singleVariableDeclaration= catchClause.getException(); >+ UnionType unionType = (UnionType) singleVariableDeclaration.getType(); >+ List types = unionType.types(); >+ assertTrue("Number of union types", types.size() == 2); >+ for (int i= types.size() - 1; i >= 0; i--) { >+ Type type2= (Type)types.get(i); >+ CatchClause newCatchClause= ast.newCatchClause(); >+ SingleVariableDeclaration newSingleVariableDeclaration= ast.newSingleVariableDeclaration(); >+ newSingleVariableDeclaration.setType((Type) rewrite.createCopyTarget(type2)); >+ newSingleVariableDeclaration.setName((SimpleName) rewrite.createCopyTarget(singleVariableDeclaration.getName())); >+ newCatchClause.setException(newSingleVariableDeclaration); >+ newCatchClause.setBody((Block) rewrite.createCopyTarget(catchClause.getBody())); >+ rewrite.getListRewrite(tryStatement, TryStatement.CATCH_CLAUSES_PROPERTY).insertAfter(newCatchClause, catchClause, null); >+ } >+ rewrite.remove(catchClause, null); >+ } >+ String preview= evaluateRewrite(cu, rewrite); >+ >+ buf= new StringBuffer(); >+ buf.append("package test1;\n"); >+ buf.append("public class E {\n"); >+ buf.append(" public void foo(int i) {\n"); >+ buf.append(" try {\n"); >+ buf.append(" System.out.println(\"foo\");\n"); >+ buf.append(" } catch (IllegalArgumentException exe)\n"); >+ buf.append(" {\n"); >+ buf.append(" System.out.println(exe);\n"); >+ buf.append(" } catch (NullPointerException exe)\n"); >+ buf.append(" {\n"); >+ buf.append(" System.out.println(exe);\n"); >+ buf.append(" }\n"); >+ buf.append(" }\n"); >+ buf.append("}\n"); >+ assertEqualString(preview, buf.toString()); >+ } finally { >+ deleteProject("P_17"); >+ } >+ } > } > > >diff --git a/org.eclipse.jdt.core.tests.model/test.xml b/org.eclipse.jdt.core.tests.model/test.xml >index ebf09ed..256892d 100644 >--- a/org.eclipse.jdt.core.tests.model/test.xml >+++ b/org.eclipse.jdt.core.tests.model/test.xml >@@ -1,6 +1,7 @@ >-<?xml version="1.0"?> >- <!-- >- Copyright (c) 2002, 2009 IBM Corporation and others. >+<?xml version="1.0" encoding="UTF-8"?> >+ >+<!-- >+ Copyright (c) 2002, 2011 IBM Corporation 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 >diff --git a/org.eclipse.jdt.core.tests.model/workspace/Converter15/bins/bug353474.jar b/org.eclipse.jdt.core.tests.model/workspace/Converter15/bins/bug353474.jar >new file mode 100644 >index 0000000..f24640e >--- /dev/null >+++ b/org.eclipse.jdt.core.tests.model/workspace/Converter15/bins/bug353474.jar >Binary files differ >diff --git a/org.eclipse.jdt.core.tests.model/workspace/JavaProjectTests/bin/bug360164.jar b/org.eclipse.jdt.core.tests.model/workspace/JavaProjectTests/bin/bug360164.jar >new file mode 100644 >index 0000000..3defaf5 >--- /dev/null >+++ b/org.eclipse.jdt.core.tests.model/workspace/JavaProjectTests/bin/bug360164.jar >Binary files differ >diff --git a/org.eclipse.jdt.core.tests.model/workspace/NullAnnotations/lib/example.jar b/org.eclipse.jdt.core.tests.model/workspace/NullAnnotations/lib/example.jar >new file mode 100644 >index 0000000..4f9b0ca >--- /dev/null >+++ b/org.eclipse.jdt.core.tests.model/workspace/NullAnnotations/lib/example.jar >Binary files differ >diff --git a/org.eclipse.jdt.core.tests.performance/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.jdt.core.tests.performance/.settings/org.eclipse.core.runtime.prefs >new file mode 100644 >index 0000000..5a0ad22 >--- /dev/null >+++ b/org.eclipse.jdt.core.tests.performance/.settings/org.eclipse.core.runtime.prefs >@@ -0,0 +1,2 @@ >+eclipse.preferences.version=1 >+line.separator=\n >diff --git a/org.eclipse.jdt.core.tests.performance/META-INF/MANIFEST.MF b/org.eclipse.jdt.core.tests.performance/META-INF/MANIFEST.MF >index b1af997..719aa72 100644 >--- a/org.eclipse.jdt.core.tests.performance/META-INF/MANIFEST.MF >+++ b/org.eclipse.jdt.core.tests.performance/META-INF/MANIFEST.MF >@@ -2,7 +2,7 @@ > Bundle-ManifestVersion: 2 > Bundle-Name: %pluginName > Bundle-SymbolicName: org.eclipse.jdt.core.tests.performance >-Bundle-Version: 3.8.0.qualifier >+Bundle-Version: 3.8.1.qualifier > Bundle-ClassPath: jdtcoretestsperf.jar > Bundle-Vendor: %providerName > Bundle-Localization: plugin >@@ -16,5 +16,6 @@ > org.eclipse.jdt.core.tests.model;bundle-version="[3.4.0,4.0.0)", > org.junit;bundle-version="3.8.1", > org.eclipse.test.performance;bundle-version="[3.1.0,4.0.0)", >- org.eclipse.text;bundle-version="[3.1.0,4.0.0)" >+ org.eclipse.text;bundle-version="[3.1.0,4.0.0)", >+ org.eclipse.jdt.core.tests.binaries;bundle-version="1.0.0" > Bundle-RequiredExecutionEnvironment: J2SE-1.4 >diff --git a/org.eclipse.jdt.core.tests.performance/build.properties b/org.eclipse.jdt.core.tests.performance/build.properties >index f685056..d962a6c 100644 >--- a/org.eclipse.jdt.core.tests.performance/build.properties >+++ b/org.eclipse.jdt.core.tests.performance/build.properties >@@ -13,10 +13,7 @@ > jdtcoretestsperf.jar,\ > local_test.xml,\ > META-INF/,\ >- plugin.properties,\ >- full-source-R3_0.zip,\ >- GenericTypeTest.java,\ >- EclipseVisitorBug.java >+ plugin.properties > src.includes = about.html > source.jdtcoretestsperf.jar = src/ > output.jdtcoretestsperf.jar = bin/ >diff --git a/org.eclipse.jdt.core.tests.performance/local_test.xml b/org.eclipse.jdt.core.tests.performance/local_test.xml >index a1d4813..3f96843 100644 >--- a/org.eclipse.jdt.core.tests.performance/local_test.xml >+++ b/org.eclipse.jdt.core.tests.performance/local_test.xml >@@ -1,5 +1,6 @@ >-<?xml version="1.0"?> >- <!-- >+<?xml version="1.0" encoding="UTF-8"?> >+ >+<!-- > Copyright (c) 2006, 2009 IBM Corporation and others. > All rights reserved. This program and the accompanying materials > are made available under the terms of the Eclipse Public License v1.0 >diff --git a/org.eclipse.jdt.core.tests.performance/src/org/eclipse/jdt/core/tests/performance/FullSourceWorkspaceBuildTests.java b/org.eclipse.jdt.core.tests.performance/src/org/eclipse/jdt/core/tests/performance/FullSourceWorkspaceBuildTests.java >index a6a35f9..a4eb402 100644 >--- a/org.eclipse.jdt.core.tests.performance/src/org/eclipse/jdt/core/tests/performance/FullSourceWorkspaceBuildTests.java >+++ b/org.eclipse.jdt.core.tests.performance/src/org/eclipse/jdt/core/tests/performance/FullSourceWorkspaceBuildTests.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -281,7 +281,7 @@ > final String targetWorkspacePath = ResourcesPlugin.getWorkspace().getRoot().getLocation().toFile().getCanonicalPath(); > String logFileName = targetWorkspacePath + File.separator + getName()+".log"; > >- String pluginDir = getPluginDirectoryPath(); >+ String pluginDir = getPluginBinariesDirectoryPath(); > String sources = ""; > for (int i=0, l=srcPaths.length; i<l; i++) { > String path = pluginDir + File.separator + srcPaths[i]; >diff --git a/org.eclipse.jdt.core.tests.performance/src/org/eclipse/jdt/core/tests/performance/FullSourceWorkspaceFormatterTests.java b/org.eclipse.jdt.core.tests.performance/src/org/eclipse/jdt/core/tests/performance/FullSourceWorkspaceFormatterTests.java >index 55f386d..7e9ff2e 100644 >--- a/org.eclipse.jdt.core.tests.performance/src/org/eclipse/jdt/core/tests/performance/FullSourceWorkspaceFormatterTests.java >+++ b/org.eclipse.jdt.core.tests.performance/src/org/eclipse/jdt/core/tests/performance/FullSourceWorkspaceFormatterTests.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -65,7 +65,7 @@ > // Read big file > System.out.print(" - Read big file source..."); > long start = System.currentTimeMillis(); >- FORMAT_TYPE_SOURCE = Util.fileContent(getPluginDirectoryPath()+File.separator+"GenericTypeTest.java"); >+ FORMAT_TYPE_SOURCE = Util.fileContent(getPluginBinariesDirectoryPath()+File.separator+"GenericTypeTest.java"); > System.out.println("("+(System.currentTimeMillis()-start)+"ms)"); > } > >diff --git a/org.eclipse.jdt.core.tests.performance/src/org/eclipse/jdt/core/tests/performance/FullSourceWorkspaceModelTests.java b/org.eclipse.jdt.core.tests.performance/src/org/eclipse/jdt/core/tests/performance/FullSourceWorkspaceModelTests.java >index 85f2071..f981e71 100644 >--- a/org.eclipse.jdt.core.tests.performance/src/org/eclipse/jdt/core/tests/performance/FullSourceWorkspaceModelTests.java >+++ b/org.eclipse.jdt.core.tests.performance/src/org/eclipse/jdt/core/tests/performance/FullSourceWorkspaceModelTests.java >@@ -347,7 +347,11 @@ > } > assertEquals(message, expected, actual); > } >- >+private void touchFiles(File[] files) { >+ for(int index=0; index < files.length; index++) { >+ files[index].setLastModified(System.currentTimeMillis()); >+ } >+} > /* > * Creates a simple Java project with no source folder and only rt.jar on its classpath. > */ >@@ -1371,6 +1375,59 @@ > System.out.println((System.currentTimeMillis()-startTime)+"ms"); > } > } >+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=354332 >+public void testRefreshExternalArchives() throws Exception { >+ int jarCount = 100; >+ File[] files = new File[jarCount]; >+ IJavaModel model = JavaCore.create(ResourcesPlugin.getWorkspace().getRoot()); >+ IClasspathEntry[] oldClasspath = BIG_PROJECT.getRawClasspath(); >+ try { >+ IClasspathEntry[] classpath = new IClasspathEntry[jarCount]; >+ for (int index = 0; index < jarCount; index++) { >+ String filePath = getExternalResourcePath("lib"+ index +".jar"); >+ org.eclipse.jdt.core.tests.util.Util.createJar(new String[0], >+ new String[] { >+ "META-INF/MANIFEST.MF", >+ "Manifest-Version: 1.0\n", >+ }, >+ filePath, >+ JavaCore.VERSION_1_4); >+ classpath[index] = JavaCore.newLibraryEntry(new Path(filePath), null, null); >+ files[index] = new File(filePath); >+ } >+ BIG_PROJECT.setRawClasspath(classpath, null); >+ >+ // warm up >+ int max = 20; >+ int warmup = WARMUP_COUNT / 10; >+ for (int i = 0; i < warmup; i++) { >+ for (int j = 0; j < max; j++) { >+ touchFiles(files); >+ model.refreshExternalArchives(new IJavaElement[] {BIG_PROJECT}, null); >+ } >+ } >+ >+ // measure performance >+ for (int i = 0; i < MEASURES_COUNT; i++) { >+ runGc(); >+ startMeasuring(); >+ for (int j = 0; j < max; j++) { >+ touchFiles(files); >+ model.refreshExternalArchives(new IJavaElement[] {BIG_PROJECT}, null); >+ } >+ stopMeasuring(); >+ } >+ >+ commitMeasurements(); >+ assertPerformance(); >+ >+ } finally { >+ BIG_PROJECT.setRawClasspath(oldClasspath, null); >+ for(int index=0; index < files.length; index++) { >+ files[index].delete(); >+ } >+ } >+} > > protected void resetCounters() { > // do nothing >diff --git a/org.eclipse.jdt.core.tests.performance/src/org/eclipse/jdt/core/tests/performance/FullSourceWorkspaceTests.java b/org.eclipse.jdt.core.tests.performance/src/org/eclipse/jdt/core/tests/performance/FullSourceWorkspaceTests.java >index ec5713b..a3ca875 100644 >--- a/org.eclipse.jdt.core.tests.performance/src/org/eclipse/jdt/core/tests/performance/FullSourceWorkspaceTests.java >+++ b/org.eclipse.jdt.core.tests.performance/src/org/eclipse/jdt/core/tests/performance/FullSourceWorkspaceTests.java >@@ -405,9 +405,9 @@ > /* > * Returns the OS path to the directory that contains this plugin. > */ >- static String getPluginDirectoryPath() { >+ static String getPluginBinariesDirectoryPath() { > try { >- URL platformURL = Platform.getBundle("org.eclipse.jdt.core.tests.performance").getEntry("/"); >+ URL platformURL = Platform.getBundle("org.eclipse.jdt.core.tests.binaries").getEntry("/"); > return new File(FileLocator.toFileURL(platformURL).getFile()).getAbsolutePath(); > } catch (IOException e) { > e.printStackTrace(); >@@ -621,7 +621,7 @@ > long start = System.currentTimeMillis(); > int dirLength = directories.length; > if (dirLength < 62) { >- String fullSourceZipPath = getPluginDirectoryPath() + File.separator + "full-source-R3_0.zip"; >+ String fullSourceZipPath = getPluginBinariesDirectoryPath() + File.separator + "full-source-R3_0.zip"; > System.out.println("Unzipping "+fullSourceZipPath); > System.out.print(" in "+targetWorkspacePath+"..."); > Util.unzip(fullSourceZipPath, targetWorkspacePath); >@@ -1246,4 +1246,20 @@ > // Return created options map > return optionsMap; > } >+ >+ protected String getExternalPath() { >+ String path = ""; >+ try { >+ path = ResourcesPlugin.getWorkspace().getRoot().getLocation().toFile().getParentFile().getCanonicalPath(); >+ if (path.charAt(path.length()-1) != File.separatorChar) >+ path += File.separatorChar; >+ } catch (IOException e) { >+ e.printStackTrace(); >+ } >+ return path; >+ } >+ >+ protected String getExternalResourcePath(String relativePath) { >+ return getExternalPath() + relativePath; >+ } > } >diff --git a/org.eclipse.jdt.core.tests.performance/test.xml b/org.eclipse.jdt.core.tests.performance/test.xml >index 6fb3f40..2e68011 100644 >--- a/org.eclipse.jdt.core.tests.performance/test.xml >+++ b/org.eclipse.jdt.core.tests.performance/test.xml >@@ -1,6 +1,7 @@ >-<?xml version="1.0"?> >- <!-- >- Copyright (c) 2004, 2009 IBM Corporation and others. >+<?xml version="1.0" encoding="UTF-8"?> >+ >+<!-- >+ Copyright (c) 2004, 2011 IBM Corporation 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 >diff --git a/org.eclipse.jdt.core/.cvsignore b/org.eclipse.jdt.core/.cvsignore >deleted file mode 100644 >index cb08788..0000000 >--- a/org.eclipse.jdt.core/.cvsignore >+++ /dev/null >@@ -1,3 +0,0 @@ >-bin >-antbin >-jdtCompilerAdapter.jar >\ No newline at end of file >diff --git a/org.eclipse.jdt.core/.settings/.api_filters b/org.eclipse.jdt.core/.settings/.api_filters >index d0a5fbf..91161cb 100644 >--- a/org.eclipse.jdt.core/.settings/.api_filters >+++ b/org.eclipse.jdt.core/.settings/.api_filters >@@ -1,359 +1,26 @@ >-<?xml version="1.0" encoding="UTF-8" standalone="no"?> >-<component id="org.eclipse.jdt.core" version="2"> >- <resource path="compiler/org/eclipse/jdt/core/compiler/CharOperation.java" type="org.eclipse.jdt.core.compiler.CharOperation"> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="compareTo(char[], char[], int, int)"/> >- </message_arguments> >- </filter> >- </resource> >- <resource path="compiler/org/eclipse/jdt/core/compiler/IProblem.java" type="org.eclipse.jdt.core.compiler.IProblem"> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="AssignmentToMultiCatchParameter"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="AssignmentToResource"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="AutoManagedResourceNotBelow17"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="BinaryLiteralNotBelow17"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="CannotInferElidedTypes"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="CannotUseDiamondWithAnonymousClasses"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="CannotUseDiamondWithExplicitTypeArguments"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="DiamondNotBelow17"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="DuplicateInheritedMethods"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="IllegalHexaLiteral"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="IllegalUnderscorePosition"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="IncorrectSwitchType17"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="InvalidBinary"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="InvalidUnionTypeReferenceSequence"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="MultiCatchNotBelow17"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="PolymorphicMethodNotBelow17"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="PotentialHeapPollutionFromVararg"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="RedundantSpecificationOfTypeArguments"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="ResourceHasToImplementAutoCloseable"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="SafeVarargsOnFixedArityMethod"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="SafeVarargsOnNonFinalInstanceMethod"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="SwitchOnStringsNotBelow17"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="UnderscoresInLiteralsNotBelow17"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="UnhandledExceptionOnAutoClose"/> >- </message_arguments> >- </filter> >- </resource> >- <resource path="dom/org/eclipse/jdt/core/dom/AST.java" type="org.eclipse.jdt.core.dom.AST"> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="JLS4"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="newUnionType()"/> >- </message_arguments> >- </filter> >- </resource> >- <resource path="dom/org/eclipse/jdt/core/dom/ASTMatcher.java" type="org.eclipse.jdt.core.dom.ASTMatcher"> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="match(UnionType, Object)"/> >- </message_arguments> >- </filter> >- </resource> >- <resource path="dom/org/eclipse/jdt/core/dom/ASTNode.java" type="org.eclipse.jdt.core.dom.ASTNode"> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="UNION_TYPE"/> >- </message_arguments> >- </filter> >- </resource> >- <resource path="dom/org/eclipse/jdt/core/dom/ASTVisitor.java" type="org.eclipse.jdt.core.dom.ASTVisitor"> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="endVisit(UnionType)"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="visit(UnionType)"/> >- </message_arguments> >- </filter> >- </resource> >- <resource path="dom/org/eclipse/jdt/core/dom/ClassInstanceCreation.java" type="org.eclipse.jdt.core.dom.ClassInstanceCreation"> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="isResolvedTypeInferredFromExpectedType()"/> >- </message_arguments> >- </filter> >- </resource> >- <resource path="dom/org/eclipse/jdt/core/dom/TryStatement.java" type="org.eclipse.jdt.core.dom.TryStatement"> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="RESOURCES_PROPERTY"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="resources()"/> >- </message_arguments> >- </filter> >- </resource> >- <resource path="dom/org/eclipse/jdt/core/dom/Type.java" type="org.eclipse.jdt.core.dom.Type"> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="isUnionType()"/> >- </message_arguments> >- </filter> >- </resource> >- <resource path="dom/org/eclipse/jdt/core/dom/UnionType.java" type="org.eclipse.jdt.core.dom.UnionType"> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1109393411"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="org.eclipse.jdt.core.dom.UnionType"/> >- </message_arguments> >- </filter> >- </resource> >- <resource path="formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java" type="org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants"> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="FORMATTER_ALIGNMENT_FOR_RESOURCES_IN_TRY"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="FORMATTER_ALIGNMENT_FOR_UNION_TYPE_IN_MULTICATCH"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_TRY"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="FORMATTER_INSERT_SPACE_AFTER_SEMICOLON_IN_TRY_RESOURCES"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_TRY"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_TRY"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="FORMATTER_INSERT_SPACE_BEFORE_SEMICOLON_IN_TRY_RESOURCES"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="FORMATTER_WRAP_BEFORE_OR_OPERATOR_MULTICATCH"/> >- </message_arguments> >- </filter> >- </resource> >- <resource path="model/org/eclipse/jdt/core/BindingKey.java" type="org.eclipse.jdt.core.BindingKey"> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="getDeclaringType()"/> >- </message_arguments> >- </filter> >- </resource> >- <resource path="model/org/eclipse/jdt/core/CompletionProposal.java" type="org.eclipse.jdt.core.CompletionProposal"> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="canUseDiamond(CompletionContext)"/> >- </message_arguments> >- </filter> >- </resource> >- <resource path="model/org/eclipse/jdt/core/JavaCore.java" type="org.eclipse.jdt.core.JavaCore"> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="COMPILER_PB_REDUNDANT_TYPE_ARGUMENTS"/> >- </message_arguments> >- </filter> >- </resource> >- <resource path="model/org/eclipse/jdt/core/Signature.java" type="org.eclipse.jdt.core.Signature"> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="C_INTERSECTION"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="INTERSECTION_TYPE_SIGNATURE"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="createIntersectionTypeSignature(String[])"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="createIntersectionTypeSignature(char[][])"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="getIntersectionTypeBounds(String)"/> >- </message_arguments> >- </filter> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="getIntersectionTypeBounds(char[])"/> >- </message_arguments> >- </filter> >- </resource> >- <resource path="model/org/eclipse/jdt/core/compiler/ReconcileContext.java" type="org.eclipse.jdt.core.compiler.ReconcileContext"> >- <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843"> >- <message_arguments> >- <message_argument value="3.7.1"/> >- <message_argument value="getAST4()"/> >- </message_arguments> >- </filter> >- </resource> >-</component> >+<?xml version="1.0" encoding="UTF-8"?><component id="org.eclipse.jdt.core" version="2"> >+ <resource path="model/org/eclipse/jdt/core/IJavaModelMarker.java" type="org.eclipse.jdt.core.IJavaModelMarker"> >+ <filter id="1210056707"> >+ <message_arguments> >+ <message_argument value="3.6.4"/> >+ <message_argument value="OUTPUT_OVERLAPPING_SOURCE"/> >+ </message_arguments> >+ </filter> >+ </resource> >+ <resource path="model/org/eclipse/jdt/core/IJavaModelStatusConstants.java" type="org.eclipse.jdt.core.IJavaModelStatusConstants"> >+ <filter id="1210056707"> >+ <message_arguments> >+ <message_argument value="3.6.4"/> >+ <message_argument value="OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE"/> >+ </message_arguments> >+ </filter> >+ </resource> >+ <resource path="model/org/eclipse/jdt/core/JavaCore.java" type="org.eclipse.jdt.core.JavaCore"> >+ <filter id="1142947843"> >+ <message_arguments> >+ <message_argument value="3.6.4"/> >+ <message_argument value="CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE"/> >+ </message_arguments> >+ </filter> >+ </resource> >+</component> >\ No newline at end of file >diff --git a/org.eclipse.jdt.core/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.jdt.core/.settings/org.eclipse.core.runtime.prefs >new file mode 100644 >index 0000000..5a0ad22 >--- /dev/null >+++ b/org.eclipse.jdt.core/.settings/org.eclipse.core.runtime.prefs >@@ -0,0 +1,2 @@ >+eclipse.preferences.version=1 >+line.separator=\n >diff --git a/org.eclipse.jdt.core/META-INF/MANIFEST.MF b/org.eclipse.jdt.core/META-INF/MANIFEST.MF >index bb3c0af..1cc07ca 100644 >--- a/org.eclipse.jdt.core/META-INF/MANIFEST.MF >+++ b/org.eclipse.jdt.core/META-INF/MANIFEST.MF >@@ -3,7 +3,7 @@ > Bundle-ManifestVersion: 2 > Bundle-Name: %pluginName > Bundle-SymbolicName: org.eclipse.jdt.core; singleton:=true >-Bundle-Version: 3.8.0.qualifier >+Bundle-Version: 3.8.1.qualifier > Bundle-Activator: org.eclipse.jdt.core.JavaCore > Bundle-Vendor: %providerName > Bundle-Localization: plugin >@@ -17,6 +17,7 @@ > org.eclipse.jdt.core.jdom, > org.eclipse.jdt.core.search, > org.eclipse.jdt.core.util, >+ org.eclipse.jdt.core.index, > org.eclipse.jdt.internal.codeassist;x-internal:=true, > org.eclipse.jdt.internal.codeassist.complete;x-internal:=true, > org.eclipse.jdt.internal.codeassist.impl;x-internal:=true, >diff --git a/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/BuildJarIndex.java b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/BuildJarIndex.java >new file mode 100644 >index 0000000..cd7238a >--- /dev/null >+++ b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/BuildJarIndex.java >@@ -0,0 +1,62 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 IBM Corporation 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.core; >+ >+import java.io.IOException; >+ >+import org.apache.tools.ant.BuildException; >+import org.apache.tools.ant.Task; >+import org.eclipse.jdt.core.index.JavaIndexer; >+import org.eclipse.jdt.internal.antadapter.AntAdapterMessages; >+ >+/** >+ * <p> >+ * An Ant task to generate the index file for the given jar path. >+ * </p> >+ * <p> >+ * <code><eclipse.buildJarIndex jarPath="Test.jar" indexPath="Test.index"/></code> >+ * </p> >+ * <p> >+ * For more information on Ant check out the website at http://jakarta.apache.org/ant/ . >+ * </p> >+ * <p> >+ * This is not intended to be subclassed by users. >+ * </p> >+ * @since 3.8 >+ */ >+public class BuildJarIndex extends Task { >+ >+ private String jarPath; >+ private String indexPath; >+ >+ public void execute() throws BuildException { >+ if (this.jarPath == null) { >+ throw new BuildException(AntAdapterMessages.getString("buildJarIndex.jarFile.cannot.be.null")); //$NON-NLS-1$ >+ } >+ if (this.indexPath == null) { >+ throw new BuildException(AntAdapterMessages.getString("buildJarIndex.indexFile.cannot.be.null")); //$NON-NLS-1$ >+ } >+ >+ try { >+ JavaIndexer.generateIndexForJar(this.jarPath, this.indexPath); >+ } catch (IOException e) { >+ throw new BuildException(AntAdapterMessages.getString("buildJarIndex.ioexception.occured", e.getLocalizedMessage())); //$NON-NLS-1$ >+ } >+ } >+ >+ public void setJarPath(String path) { >+ this.jarPath = path; >+ } >+ >+ public void setIndexPath(String path) { >+ this.indexPath = path; >+ } >+} >diff --git a/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/internal/antadapter/messages.properties b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/internal/antadapter/messages.properties >index df61656..9cb9be2 100644 >--- a/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/internal/antadapter/messages.properties >+++ b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/internal/antadapter/messages.properties >@@ -1,5 +1,5 @@ > ############################################################################### >-# Copyright (c) 2000, 2006 IBM Corporation and others. >+# Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -19,3 +19,7 @@ > checkDebugAttributes.property.argument.cannot.be.null=The property argument cannot be null > checkDebugAttributes.ioexception.occured=IOException occurred while reading > checkDebugAttributes.file.argument.must.be.a.classfile.or.a.jarfile=The file argument must be a .class or a .jar file >+ >+buildJarIndex.jarFile.cannot.be.null=The jar file argument cannot be null >+buildJarIndex.indexFile.cannot.be.null=The index file argument cannot be null >+buildJarIndex.ioexception.occured=IOException - {0} >diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/core/compiler/batch/package.html b/org.eclipse.jdt.core/batch/org/eclipse/jdt/core/compiler/batch/package.html >new file mode 100644 >index 0000000..cf3bc8a >--- /dev/null >+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/core/compiler/batch/package.html >@@ -0,0 +1,16 @@ >+<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> >+<html> >+<head> >+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> >+ <meta name="Author" content="IBM"> >+ <meta name="GENERATOR" content="Mozilla/4.73 [en] (Windows NT 5.0; U) [Netscape]"> >+ <title>Package-level Javadoc</title> >+</head> >+<body> >+This package contains the batch compiler API. >+<h2> >+Package Specification</h2> >+ >+<p><br>This package contains the batch compiler API. >+</body> >+</html> >diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/CompilationUnit.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/CompilationUnit.java >index 0166e87..64d3d89 100644 >--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/CompilationUnit.java >+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/CompilationUnit.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -31,12 +31,17 @@ > // == Main.NONE: absorbent element, do not output class files; > // else: use as the path of the directory into which class files must > // be written. >+ private boolean ignoreOptionalProblems; > > public CompilationUnit(char[] contents, String fileName, String encoding) { > this(contents, fileName, encoding, null); > } > public CompilationUnit(char[] contents, String fileName, String encoding, > String destinationPath) { >+ this(contents, fileName, encoding, destinationPath, false); >+} >+public CompilationUnit(char[] contents, String fileName, String encoding, >+ String destinationPath, boolean ignoreOptionalProblems) { > this.contents = contents; > char[] fileNameCharArray = fileName.toCharArray(); > switch(File.separatorChar) { >@@ -61,6 +66,7 @@ > this.mainTypeName = CharOperation.subarray(fileNameCharArray, start, end); > this.encoding = encoding; > this.destinationPath = destinationPath; >+ this.ignoreOptionalProblems = ignoreOptionalProblems; > } > public char[] getContents() { > if (this.contents != null) >@@ -86,6 +92,9 @@ > public char[][] getPackageName() { > return null; > } >+public boolean ignoreOptionalProblems() { >+ return this.ignoreOptionalProblems; >+} > public String toString() { > return "CompilationUnit[" + new String(this.fileName) + "]"; //$NON-NLS-2$ //$NON-NLS-1$ > } >diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java >index 3cfdf2b..97a9654 100644 >--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java >+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -10,8 +10,11 @@ > * Tom Tromey - Contribution for bug 125961 > * Tom Tromey - Contribution for bug 159641 > * Benjamin Muskalla - Contribution for bug 239066 >- * Stephan Herrmann - Contribution for bug 236385 >- * Stephan Herrmann - Contribution for bug 295551 >+ * Stephan Herrmann - Contributions for >+ * bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used >+ * bug 295551 - Add option to automatically promote all warnings to errors >+ * bug 359721 - [options] add command line option for new warning token "resource" >+ * bug 365208 - [compiler][batch] command line options for annotation based null analysis > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.batch; > >@@ -1320,6 +1323,7 @@ > public Logger logger; > public int maxProblems; > public Map options; >+ public char[][] ignoreOptionalProblemsFromFolders; > protected PrintWriter out; > public boolean proceed = true; > public boolean proceedOnError = false; >@@ -1836,6 +1840,42 @@ > > switch(mode) { > case DEFAULT : >+ if (currentArg.startsWith("-nowarn")) { //$NON-NLS-1$ >+ switch (currentArg.length()) { >+ case 7: >+ disableAll(ProblemSeverities.Warning); >+ break; >+ case 8: >+ throw new IllegalArgumentException(this.bind( >+ "configure.invalidNowarnOption", currentArg)); //$NON-NLS-1$ >+ default: >+ int foldersStart = currentArg.indexOf('[') + 1; >+ int foldersEnd = currentArg.lastIndexOf(']'); >+ if (foldersStart <= 8 || foldersEnd == -1 || foldersStart > foldersEnd >+ || foldersEnd < currentArg.length() - 1) { >+ throw new IllegalArgumentException(this.bind( >+ "configure.invalidNowarnOption", currentArg)); //$NON-NLS-1$ >+ } >+ String folders = currentArg.substring(foldersStart, foldersEnd); >+ if (folders.length() > 0) { >+ char[][] currentFolders = decodeIgnoreOptionalProblemsFromFolders(folders); >+ if (this.ignoreOptionalProblemsFromFolders != null) { >+ int length = this.ignoreOptionalProblemsFromFolders.length + currentFolders.length; >+ char[][] tempFolders = new char[length][]; >+ System.arraycopy(this.ignoreOptionalProblemsFromFolders, 0, tempFolders, 0, this.ignoreOptionalProblemsFromFolders.length); >+ System.arraycopy(currentFolders, 0, tempFolders, this.ignoreOptionalProblemsFromFolders.length, currentFolders.length); >+ this.ignoreOptionalProblemsFromFolders = tempFolders; >+ } else { >+ this.ignoreOptionalProblemsFromFolders = currentFolders; >+ } >+ } else { >+ throw new IllegalArgumentException(this.bind( >+ "configure.invalidNowarnOption", currentArg)); //$NON-NLS-1$ >+ } >+ } >+ mode = DEFAULT; >+ continue; >+ } > if (currentArg.startsWith("[")) { //$NON-NLS-1$ > throw new IllegalArgumentException( > this.bind("configure.unexpectedBracket", //$NON-NLS-1$ >@@ -2186,17 +2226,12 @@ > throw new IllegalArgumentException( > this.bind("configure.invalidDebugOption", debugOption)); //$NON-NLS-1$ > } >- if (currentArg.startsWith("-nowarn")) { //$NON-NLS-1$ >- disableWarnings(); >- mode = DEFAULT; >- continue; >- } > if (currentArg.startsWith("-warn")) { //$NON-NLS-1$ > mode = DEFAULT; > String warningOption = currentArg; > int length = currentArg.length(); > if (length == 10 && warningOption.equals("-warn:" + NONE)) { //$NON-NLS-1$ >- disableWarnings(); >+ disableAll(ProblemSeverities.Warning); > continue; > } > if (length <= 6) { >@@ -2204,23 +2239,20 @@ > this.bind("configure.invalidWarningConfiguration", warningOption)); //$NON-NLS-1$ > } > int warnTokenStart; >- boolean isEnabling, allowPlusOrMinus; >+ boolean isEnabling; > switch (warningOption.charAt(6)) { > case '+' : > warnTokenStart = 7; > isEnabling = true; >- allowPlusOrMinus = true; > break; > case '-' : > warnTokenStart = 7; > isEnabling = false; // specified warnings are disabled >- allowPlusOrMinus = true; > break; > default: >- disableWarnings(); >+ disableAll(ProblemSeverities.Warning); > warnTokenStart = 6; > isEnabling = true; >- allowPlusOrMinus = false; > } > > StringTokenizer tokenizer = >@@ -2236,22 +2268,12 @@ > tokenCounter++; > switch(token.charAt(0)) { > case '+' : >- if (allowPlusOrMinus) { >- isEnabling = true; >- token = token.substring(1); >- } else { >- throw new IllegalArgumentException( >- this.bind("configure.invalidUsageOfPlusOption", token)); //$NON-NLS-1$ >- } >+ isEnabling = true; >+ token = token.substring(1); > break; > case '-' : >- if (allowPlusOrMinus) { >- isEnabling = false; >- token = token.substring(1); >- } else { >- throw new IllegalArgumentException( >- this.bind("configure.invalidUsageOfMinusOption", token)); //$NON-NLS-1$ >- } >+ isEnabling = false; >+ token = token.substring(1); > } > handleWarningToken(token, isEnabling); > } >@@ -2270,23 +2292,20 @@ > this.bind("configure.invalidErrorConfiguration", errorOption)); //$NON-NLS-1$ > } > int errorTokenStart; >- boolean isEnabling, allowPlusOrMinus; >+ boolean isEnabling; > switch (errorOption.charAt(5)) { > case '+' : > errorTokenStart = 6; > isEnabling = true; >- allowPlusOrMinus = true; > break; > case '-' : > errorTokenStart = 6; > isEnabling = false; // specified errors are disabled >- allowPlusOrMinus = true; > break; > default: >- disableErrors(); >+ disableAll(ProblemSeverities.Error); > errorTokenStart = 5; > isEnabling = true; >- allowPlusOrMinus = false; > } > > StringTokenizer tokenizer = >@@ -2298,22 +2317,12 @@ > tokenCounter++; > switch(token.charAt(0)) { > case '+' : >- if (allowPlusOrMinus) { >- isEnabling = true; >- token = token.substring(1); >- } else { >- throw new IllegalArgumentException( >- this.bind("configure.invalidUsageOfPlusOption", token)); //$NON-NLS-1$ >- } >+ isEnabling = true; >+ token = token.substring(1); > break; > case '-' : >- if (allowPlusOrMinus) { >- isEnabling = false; >- token = token.substring(1); >- } else { >- throw new IllegalArgumentException( >- this.bind("configure.invalidUsageOfMinusOption", token)); //$NON-NLS-1$ >- } >+ isEnabling = false; >+ token = token.substring(1); > break; > } > handleErrorToken(token, isEnabling); >@@ -2401,6 +2410,10 @@ > } > if (currentArg.equals("-properties")) { //$NON-NLS-1$ > mode = INSIDE_WARNINGS_PROPERTIES; >+ continue; >+ } >+ if (currentArg.equals("-nonNullByDefault")) { //$NON-NLS-1$ >+ this.options.put(CompilerOptions.OPTION_NonNullIsDefault, CompilerOptions.ENABLED); > continue; > } > break; >@@ -2778,6 +2791,31 @@ > this.pendingErrors = null; > } > } >+ >+private static char[][] decodeIgnoreOptionalProblemsFromFolders(String folders) { >+ StringTokenizer tokenizer = new StringTokenizer(folders, File.pathSeparator); >+ char[][] result = new char[tokenizer.countTokens()][]; >+ int count = 0; >+ while (tokenizer.hasMoreTokens()) { >+ String fileName = tokenizer.nextToken(); >+ // relative folder names are created relative to the current user dir >+ File file = new File(fileName); >+ if (file.exists()) { >+ // if the file exists, we should try to use its canonical path >+ try { >+ result[count++] = file.getCanonicalPath().toCharArray(); >+ } catch (IOException e) { >+ // if we got exception during canonicalization, fall back to the name that was specified >+ result[count++] = fileName.toCharArray(); >+ } >+ } else { >+ // if the file does not exist, use the name that was specified >+ result[count++] = fileName.toCharArray(); >+ } >+ } >+ return result; >+} >+ > private static String getAllEncodings(Set encodings) { > int size = encodings.size(); > String[] allEncodings = new String[size]; >@@ -2824,7 +2862,16 @@ > } > } > } >-protected void disableWarnings() { >+protected void enableAll(int severity) { >+ String newValue = null; >+ switch(severity) { >+ case ProblemSeverities.Error : >+ newValue = CompilerOptions.ERROR; >+ break; >+ case ProblemSeverities.Warning : >+ newValue = CompilerOptions.WARNING; >+ break; >+ } > Object[] entries = this.options.entrySet().toArray(); > for (int i = 0, max = entries.length; i < max; i++) { > Map.Entry entry = (Map.Entry) entries[i]; >@@ -2832,13 +2879,22 @@ > continue; > if (!(entry.getValue() instanceof String)) > continue; >- if (((String) entry.getValue()).equals(CompilerOptions.WARNING)) { >- this.options.put(entry.getKey(), CompilerOptions.IGNORE); >+ if (((String) entry.getValue()).equals(CompilerOptions.IGNORE)) { >+ this.options.put(entry.getKey(), newValue); > } > } > this.options.put(CompilerOptions.OPTION_TaskTags, Util.EMPTY_STRING); > } >-protected void disableErrors() { >+protected void disableAll(int severity) { >+ String checkedValue = null; >+ switch(severity) { >+ case ProblemSeverities.Error : >+ checkedValue = CompilerOptions.ERROR; >+ break; >+ case ProblemSeverities.Warning : >+ checkedValue = CompilerOptions.WARNING; >+ break; >+ } > Object[] entries = this.options.entrySet().toArray(); > for (int i = 0, max = entries.length; i < max; i++) { > Map.Entry entry = (Map.Entry) entries[i]; >@@ -2846,7 +2902,7 @@ > continue; > if (!(entry.getValue() instanceof String)) > continue; >- if (((String) entry.getValue()).equals(CompilerOptions.ERROR)) { >+ if (((String) entry.getValue()).equals(checkedValue)) { > this.options.put(entry.getKey(), CompilerOptions.IGNORE); > } > } >@@ -2914,8 +2970,15 @@ > String encoding = this.encodings[i]; > if (encoding == null) > encoding = defaultEncoding; >- units[i] = new CompilationUnit(null, this.filenames[i], encoding, >- this.destinationPaths[i]); >+ String fileName; >+ try { >+ fileName = file.getCanonicalPath(); >+ } catch (IOException e) { >+ // if we got exception during canonicalization, fall back to the name that was specified >+ fileName = this.filenames[i]; >+ } >+ units[i] = new CompilationUnit(null, fileName, encoding, this.destinationPaths[i], >+ shouldIgnoreOptionalProblems(this.ignoreOptionalProblemsFromFolders, fileName.toCharArray())); > } > return units; > } >@@ -3251,6 +3314,13 @@ > setSeverity(CompilerOptions.OPTION_ReportMethodCanBeStatic, severity, isEnabling); > setSeverity(CompilerOptions.OPTION_ReportMethodCanBePotentiallyStatic, severity, isEnabling); > return; >+ } else if (token.equals("all")) { //$NON-NLS-1$ >+ if (isEnabling) { >+ enableAll(severity); >+ } else { >+ disableAll(severity); >+ } >+ return; > } > break; > case 'b' : >@@ -3403,7 +3473,37 @@ > setSeverity(CompilerOptions.OPTION_ReportRedundantNullCheck, ProblemSeverities.Ignore, isEnabling); > } > return; >+ } else if (token.startsWith("nullAnnot")) { //$NON-NLS-1$ >+ String annotationNames = Util.EMPTY_STRING; >+ int start = token.indexOf('('); >+ int end = token.indexOf(')'); >+ String nonNullAnnotName = null, nullableAnnotName = null, nonNullByDefaultAnnotName = null; >+ if (isEnabling && start >= 0 && end >= 0 && start < end){ >+ annotationNames = token.substring(start+1, end).trim(); >+ int separator1 = annotationNames.indexOf('|'); >+ if (separator1 == -1) throw new IllegalArgumentException(this.bind("configure.invalidNullAnnot", token)); //$NON-NLS-1$ >+ nullableAnnotName = annotationNames.substring(0, separator1).trim(); >+ if (nullableAnnotName.length() == 0) throw new IllegalArgumentException(this.bind("configure.invalidNullAnnot", token)); //$NON-NLS-1$ >+ int separator2 = annotationNames.indexOf('|', separator1 + 1); >+ if (separator2 == -1) throw new IllegalArgumentException(this.bind("configure.invalidNullAnnot", token)); //$NON-NLS-1$ >+ nonNullAnnotName = annotationNames.substring(separator1 + 1, separator2).trim(); >+ if (nonNullAnnotName.length() == 0) throw new IllegalArgumentException(this.bind("configure.invalidNullAnnot", token)); //$NON-NLS-1$ >+ nonNullByDefaultAnnotName = annotationNames.substring(separator2 + 1).trim(); >+ if (nonNullByDefaultAnnotName.length() == 0) throw new IllegalArgumentException(this.bind("configure.invalidNullAnnot", token)); //$NON-NLS-1$ >+ this.options.put(CompilerOptions.OPTION_NullableAnnotationName, nullableAnnotName); >+ this.options.put(CompilerOptions.OPTION_NonNullAnnotationName, nonNullAnnotName); >+ this.options.put(CompilerOptions.OPTION_NonNullByDefaultAnnotationName, nonNullByDefaultAnnotName); >+ } >+ this.options.put( >+ CompilerOptions.OPTION_AnnotationBasedNullAnalysis, >+ isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED); >+ setSeverity(CompilerOptions.OPTION_ReportNullSpecViolation, severity, isEnabling); >+ setSeverity(CompilerOptions.OPTION_ReportPotentialNullSpecViolation, severity, isEnabling); >+ setSeverity(CompilerOptions.OPTION_ReportNullSpecInsufficientInfo, severity, isEnabling); >+ setSeverity(CompilerOptions.OPTION_ReportRedundantNullAnnotation, severity, isEnabling); >+ return; > } >+ > break; > case 'o' : > if (token.equals("over-sync") /*|| token.equals("syncOverride")*/) { //$NON-NLS-1$ >@@ -3432,6 +3532,11 @@ > return; > } else if (/*token.equals("intfRedundant") ||*/ token.equals("redundantSuperinterface")) { //$NON-NLS-1$ > setSeverity(CompilerOptions.OPTION_ReportRedundantSuperinterface, severity, isEnabling); >+ return; >+ } else if (token.equals("resource")) { //$NON-NLS-1$ >+ setSeverity(CompilerOptions.OPTION_ReportUnclosedCloseable, severity, isEnabling); >+ setSeverity(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, severity, isEnabling); >+ setSeverity(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, severity, isEnabling); > return; > } > break; >@@ -3610,6 +3715,7 @@ > this.err = errWriter; > this.systemExitWhenFinished = systemExit; > this.options = new CompilerOptions().getMap(); >+ this.ignoreOptionalProblemsFromFolders = null; > > this.progress = compilationProgress; > if (customDefaultOptions != null) { >@@ -3646,7 +3752,20 @@ > this.logger.logIncorrectVMVersionForAnnotationProcessing(); > } > } >- >+private static boolean isParentOf(char[] folderName, char[] fileName) { >+ if (folderName.length >= fileName.length) { >+ return false; >+ } >+ if (fileName[folderName.length] != '\\' && fileName[folderName.length] != '/') { >+ return false; >+ } >+ for (int i = folderName.length - 1; i >= 0; i--) { >+ if (folderName[i] != fileName[i]) { >+ return false; >+ } >+ } >+ return true; >+} > // Dump classfiles onto disk for all compilation units that where successful > // and do not carry a -d none spec, either directly or inherited from Main. > public void outputClassFiles(CompilationResult unitResult) { >@@ -4192,6 +4311,18 @@ > classpaths.toArray(this.checkedClasspaths); > this.logger.logClasspath(this.checkedClasspaths); > } >+private static boolean shouldIgnoreOptionalProblems(char[][] folderNames, char[] fileName) { >+ if (folderNames == null || fileName == null) { >+ return false; >+ } >+ for (int i = 0, max = folderNames.length; i < max; i++) { >+ char[] folderName = folderNames[i]; >+ if (isParentOf(folderName, fileName)) { >+ return true; >+ } >+ } >+ return false; >+} > protected void validateOptions(boolean didSpecifyCompliance) { > if (didSpecifyCompliance) { > Object version = this.options.get(CompilerOptions.OPTION_Compliance); >diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties >index a92963b..85eeee1 100644 >--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties >+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties >@@ -1,5 +1,5 @@ > ############################################################################### >-# Copyright (c) 2000, 2011 IBM Corporation and others. >+# Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -8,6 +8,11 @@ > # Contributors: > # IBM Corporation - initial API and implementation > # Benjamin Muskalla - Contribution for bug 239066 >+# Stephan Herrmann - Contributions for >+# bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used >+# bug 295551 - Add option to automatically promote all warnings to errors >+# bug 359721 - [options] add command line option for new warning token "resource" >+# bug 365208 - [compiler][batch] command line options for annotation based null analysis > ############################################################################### > ### JavaBatchCompiler messages. > >@@ -15,7 +20,7 @@ > #Format: compiler.name = word1 word2 word3 > compiler.name = Eclipse Compiler for Java(TM) > #Format: compiler.version = 0.XXX[, other words (don't forget the comma if adding other words)] >-compiler.version = 0.C08, 3.8.0 M2 >+compiler.version = 0.C36, 3.8.0 M6 > compiler.copyright = Copyright IBM Corp 2000, 2011. All rights reserved. > > ### progress >@@ -62,12 +67,11 @@ > configure.incompatibleComplianceForTarget = Compliance level ''{0}'' is incompatible with target level ''{1}''. A compliance level ''{1}'' or better is required > configure.repetition = repetition must be a positive integer: {0} > configure.maxProblems = max problems must be a positive integer: {0} >+configure.invalidNowarnOption = invalid syntax for nowarn option: {0} > > configure.invalidErrorConfiguration = invalid error configuration: ''{0}'' > configure.invalidError = invalid error token: ''{0}''. Ignoring this error token and compiling > configure.invalidErrorOption = invalid error option: ''{0}''. Must specify an error token >-configure.invalidUsageOfPlusOption=usage of ''+'' for ''{0}'' is illegal there >-configure.invalidUsageOfMinusOption=usage of ''-'' for ''{0}'' is illegal there > > ## configure.directoryNotExist = directory does not exist: {0} > configure.unrecognizedOption = Unrecognized option : {0} >@@ -100,6 +104,9 @@ > configure.multipleencodings=Multiple encoding specified: {1}. The default encoding has been set to {0} > configure.differentencodings=Found encoding {0}. Different encodings were specified: {1} > configure.differentencoding=Found encoding {0}. A different encoding was specified: {1} >+ >+### null annotations >+configure.invalidNullAnnot = Token {0} is not in the expected format "nullAnnot(<non null annotation name> | <nullable annotation name> | <non-null by default annotation name>)" > > ### requestor > requestor.error = {0}. ERROR in {1} >@@ -181,6 +188,9 @@ > \ -deprecation + deprecation outside deprecated code (equivalent to\n\ > \ -warn:+deprecation)\n\ > \ -nowarn -warn:none disable all warnings\n\ >+\ -nowarn:[<directories separated by {0}>]\n\ >+\ specify directories from which optional problems should\n\ >+\ be ignored\n\ > \ -?:warn -help:warn display advanced warning options\n\ > \ \n\ > \ Error options:\n\ >@@ -245,6 +255,8 @@ > \ -enableJavadoc consider references in javadoc\n\ > \ -Xemacs used to enable emacs-style output in the console.\n\ > \ It does not affect the xml log output\n\ >+\ -nonNullByDefault for annotation based null analysis assume nonnull\n\ >+\ as the global default\n\ > \ \n\ > \ -? -help print this help message\n\ > \ -v -version print compiler version\n\ >@@ -262,9 +274,13 @@ > \ Warning options:\n\ > \ -deprecation + deprecation outside deprecated code\n\ > \ -nowarn -warn:none disable all warnings\n\ >+\ -nowarn:[<directories separated by {0}>]\n\ >+\ specify directories from which optional problems should\n\ >+\ be ignored\n\ > \ -warn:<warnings separated by ,> enable exactly the listed warnings\n\ > \ -warn:+<warnings separated by ,> enable additional warnings\n\ > \ -warn:-<warnings separated by ,> disable specific warnings\n\ >+\ all enable all warnings\n\ > \ allDeadCode dead code including trivial if(DEBUG) check\n\ > \ allDeprecation deprecation including inside deprecated code\n\ > \ allJavadoc invalid or missing javadoc\n\ >@@ -303,11 +319,15 @@ > \ nls string literal lacking non-nls tag //$NON-NLS-<n>$\n\ > \ noEffectAssign + assignment without effect\n\ > \ null potential missing or redundant null check\n\ >+\ nullAnnot(<annot. names separated by |>) + annotation based null analysis,\n\ >+\ nullable|nonnull|nonnullbydefault annotation types\n\ >+\ optionally specified using fully qualified names\n\ > \ nullDereference + missing null check\n\ > \ over-ann missing @Override annotation (superclass)\n\ > \ paramAssign assignment to a parameter\n\ > \ pkgDefaultMethod + attempt to override package-default method\n\ > \ raw + usage of raw type\n\ >+\ resource + (pot.) unsafe usage of resource of type Closeable\n\ > \ semicolon unnecessary semicolon, empty statement\n\ > \ serial + missing serialVersionUID\n\ > \ specialParamHiding constructor or setter parameter hiding a field\n\ >diff --git a/org.eclipse.jdt.core/build.properties b/org.eclipse.jdt.core/build.properties >index ff520f9..8e3f678 100644 >--- a/org.eclipse.jdt.core/build.properties >+++ b/org.eclipse.jdt.core/build.properties >@@ -1,5 +1,5 @@ > ############################################################################### >-# Copyright (c) 2000, 2010 IBM Corporation and others. >+# Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -24,7 +24,8 @@ > org.eclipse.jdt.core.jdom.*,\ > org.eclipse.jdt.core.dom.*,\ > org.eclipse.jdt.core.dom.rewrite.*,\ >- org.eclipse.jdt.core.search.* >+ org.eclipse.jdt.core.search.*,\ >+ org.eclipse.jdt.core.index.* > source.. = batch/,\ > codeassist/,\ > compiler/,\ >diff --git a/org.eclipse.jdt.core/buildnotes_jdt-core.html b/org.eclipse.jdt.core/buildnotes_jdt-core.html >index 7bcca82..e0bc357 100644 >--- a/org.eclipse.jdt.core/buildnotes_jdt-core.html >+++ b/org.eclipse.jdt.core/buildnotes_jdt-core.html >@@ -42,17 +42,1121 @@ > </td> > </tr> > </table> >+<a name="v_C36"></a> >+<hr><h1> >+Eclipse Platform Build Notes<br> >+Java development tools core</h1> >+Eclipse SDK 3.8.0 - %date% - 3.8.0 M6 >+<br>Project org.eclipse.jdt.core v_C36 >+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_C36">cvs</a>). >+<h2>What's new in this drop</h2> >+ >+<h3>Problem Reports Fixed</h3> >+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=372351">372351</a> >+Illegal implementation of 'org.eclipse.jdt.internal.compiler.env.ICompilationUnit' in Tomcat Jasper >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=220928">220928</a> >+[buildpath] Should be able to ignore warnings from certain source folders >+ >+<a name="v_C35"></a> >+<hr><h1> >+Eclipse Platform Build Notes<br> >+Java development tools core</h1> >+Eclipse SDK 3.8.0 - February 21, 2012 >+<br>Project org.eclipse.jdt.core v_C35 >+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_C35">cvs</a>). >+<h2>What's new in this drop</h2> >+ >+<h3>Problem Reports Fixed</h3> >+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365499">365499</a> >+Add a system property to control for JavaModelManager's jar type cache size >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=368152">368152</a> >+ConcurrentModificationException on startup in ExternalFoldersManager.createPendingFolders >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=244544">244544</a> >+codeSelect fails on constant declaration in anonymous and local classes >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=291040">291040</a> >+codeSelect(..) does not work for a deeply nested method invocation in nested and anonymous class >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=370930">370930</a> >+NonNull annotation not considered for enhanced for loops >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=366063">366063</a> >+Compiler should not add synthetic @NonNull annotations >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365531">365531</a> >+[compiler][null] investigate alternative strategy for internally encoding nullness defaults >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=370639">370639</a> >+[compiler][resource] restore the default for resource leak warnings >+ >+<a name="v_C34"></a> >+<hr><h1> >+Eclipse Platform Build Notes<br> >+Java development tools core</h1> >+Eclipse SDK 3.8.0 - February 14, 2012 >+<br> >+<h2>What's new in this drop</h2> >+ >+<h3>Problem Reports Fixed</h3> >+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=123836">123836</a> >+[1.5][search] for references to overriding method with bound type variable is not polymorphic >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=368546">368546</a> >+[compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=364254">364254</a> >+Reduce console output during JDT/Core junits execution. >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=362633">362633</a> >+NPE while trying to rename a class >+ >+<a name="v_C33"></a> >+<hr><h1> >+Eclipse Platform Build Notes<br> >+Java development tools core</h1> >+Eclipse SDK 3.8.0 - January 25, 2012 - 3.8.0 M5 >+<br> >+<h2>What's new in this drop</h2> >+ >+<h3>Problem Reports Fixed</h3> >+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=369595">369595</a> >+Javadoc fixes for IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING >+ >+<a name="v_C32"></a> >+<hr><h1> >+Eclipse Platform Build Notes<br> >+Java development tools core</h1> >+Eclipse SDK 3.8.0 - January 24, 2012 >+<br> >+<h2>What's new in this drop</h2> >+ >+<h3>Problem Reports Fixed</h3> >+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=366829">366829</a> >+Batch compiler option and SuppressWarnings token for Overriding a Synchronized Method with a Non-synchronized Method >+ >+<a name="v_C31"></a> >+<hr><h1> >+Eclipse Platform Build Notes<br> >+Java development tools core</h1> >+Eclipse SDK 3.8.0 - January 22, 2012 >+<br> >+<h2>What's new in this drop</h2> >+ >+<h3>Problem Reports Fixed</h3> >+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=369251">369251</a> >+Starved worker threads >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365208">365208</a> >+[compiler][batch] command line options for annotation based null analysis >+ >+<a name="v_C30"></a> >+<hr><h1> >+Eclipse Platform Build Notes<br> >+Java development tools core</h1> >+Eclipse SDK 3.8.0 - January 20, 2012 >+<br> >+<h2>What's new in this drop</h2> >+<ul> >+<li>New constant for the name of the encoding to be used for source attachments in IClasspathAttribute (see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=361356">361356</a> for details) >+<pre> >+ /** >+ * Constant for the name of the encoding to be used for source attachments. >+ * >+ * <p>The value of this attribute has to be a string representation of a valid encoding. The encoding >+ * for a source attachment is determined in the following order: </p> >+ * >+ * <ul> >+ * <li> Encoding explicitly set on the source file (java or zip), i.e. <code>org.eclipse.core.resources.IFile#getCharset(false)</code> </li> >+ * <li> Encoding set on the corresponding classpath entry </li> >+ * <li> If the source attachment is a member of the project, then the project's default charSet</li> >+ * <li> Workspace default charSet </li> >+ * </ul> >+ * >+ * @since 3.8 >+ */ >+ String SOURCE_ATTACHMENT_ENCODING = "source_encoding"; >+</pre> >+</li> >+<li> New IProblems for messages relating to contradictory or redundant null annotations >+<pre> >+ /** @since 3.8 */ >+ int RedundantNullDefaultAnnotation = Internal + 925; >+ /** @since 3.8 */ >+ int RedundantNullDefaultAnnotationPackage = Internal + 926; >+ /** @since 3.8 */ >+ int RedundantNullDefaultAnnotationType = Internal + 927; >+ /** @since 3.8 */ >+ int RedundantNullDefaultAnnotationMethod = Internal + 928; >+ /** @since 3.8 */ >+ int ContradictoryNullAnnotations = Internal + 929; >+</pre> >+</li> >+</ul> >+<h3>Problem Reports Fixed</h3> >+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=361356">361356</a> >+Allow to specify encoding for source attachments >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365582">365582</a> >+FUP of bug 361938: Other error code pattern >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365662">365662</a> >+[compiler][null] warn on contradictory and redundant null annotations >+ >+<a name="v_C29"></a> >+<hr><h1> >+Eclipse Platform Build Notes<br> >+Java development tools core</h1> >+Eclipse SDK 3.8.0 - January 17, 2012 >+<br> >+<h2>What's new in this drop</h2> >+ >+<h3>Problem Reports Fixed</h3> >+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=368842">368842</a> >+test failure because test case refers to java.util.Objects >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=368709">368709</a> >+Endless loop in FakedTrackingVariable.markPassedToOutside >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=361407">361407</a> >+Resource leak warning when resource is assigned to a field outside of constructor >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=362331">362331</a> >+Resource leak not detected when closeable not assigned to variable >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=362332">362332</a> >+Only report potential leak when closeable not created in the local scope >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=360908">360908</a> >+Avoid resource leak warning when the underlying/chained resource is closed explicitly >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=361073">361073</a> >+Avoid resource leak warning when the top level resource is closed explicitly >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=358903">358903</a> >+Filter practically unimportant resource leak warnings >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365387">365387</a> >+[compiler][null] bug 186342: Issues to follow up post review and verification. >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365519">365519</a> >+editorial cleanup after bug 186342 and bug 365387 >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=368435">368435</a> >+[compiler] NPE while compile a method with unused local >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=361963">361963</a> >+Stack overflow when trying to code complete a generic list >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365437">365437</a> >+Private methods tagged with @Inject should not be flagged with unused warning >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=366131">366131</a> >+[1.5][compiler] New generics compile error in Indigo SR1 for code that compiles in earlier Eclipse and javac >+ >+<a name="v_C28"></a> >+<hr><h1> >+Eclipse Platform Build Notes<br> >+Java development tools core</h1> >+Eclipse SDK 3.8.0 - January 10, 2012 >+<h2>What's new in this drop</h2> >+ >+<h3>Problem Reports Fixed</h3> >+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023">367023</a> >+Error in JDT Core during AST creation >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=354229">354229</a> >+[compiler][1.7] Name clash error not being reported by ecj. >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=367879">367879</a> >+Incorrect "Potential null pointer access" warning on statement after try-with-resources within try-finally >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=366999">366999</a> >+VerifyError: Inconsistent stackmap frames >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=346175">346175</a> >+@SuppressWarnings should clear all errors including fatal optional errors >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=366544">366544</a> >+[index] Test testUseIndexInternalJarAfterRestart failed on Mac and Linux >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=302850">302850</a> >+13 failures in JavaModel tests for the N20100214-2000 Mac OS X - Cocoa test machine >+ >+<a name="v_C27"></a> >+<hr><h1> >+Eclipse Platform Build Notes<br> >+Java development tools core</h1> >+Eclipse SDK 3.8.0 - January 3, 2012 - 3.8.0 M5 >+<br> >+<h2>What's new in this drop</h2> >+ >+<h3>Problem Reports Fixed</h3> >+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=367566">367566</a> >+In try-with-resources statement close() method of resource is not called >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=364890">364890</a> >+BinaryTypeBinding should use char constants from Util >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365992">365992</a> >+[builder] [null] Change of nullness for a parameter doesn't trigger a build for the files that call the method >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=367203">367203</a> >+[compiler][null] detect assigning null to nonnull argument >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=367154">367154</a> >+[compiler][null] Problem in propagating null defaults. >+ >+<a name="v_C26"></a> >+<hr><h1> >+Eclipse Platform Build Notes<br> >+Java development tools core</h1> >+Eclipse SDK 3.8.0 - December 20, 2011 >+<h2>What's new in this drop</h2> >+ >+<h3>Problem Reports Fixed</h3> >+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=362711">362711</a> >+possibly incorrect JDT POST_CHANGE event fired when a file is replaced >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365835">365835</a> >+[compiler][null] inconsistent error reporting. >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365836">365836</a> >+[compiler][null] Incomplete propagation of null defaults. >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365983">365983</a> >+[compiler][null] AIOOB with null annotation analysis and varargs >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=366003">366003</a> >+CCE in ASTNode.resolveAnnotations(ASTNode.java:639) >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=366829">366829</a> >+Batch compiler option and SuppressWarnings token for Overriding a Synchronized Method with a Non-synchronized Method >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=364450">364450</a> >+Dubious class path error triggers a full rebuild >+ >+<a name="v_C25"></a> >+<hr><h1> >+Eclipse Platform Build Notes<br> >+Java development tools core</h1> >+Eclipse SDK 3.8.0 - December 13, 2011 >+<h2>What's new in this drop</h2> >+<ul> >+<li>New constant for the name of index location class path attribute in IClasspathAttribute(see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=356620">356620</a> for details) >+<pre> >+ /** >+ * Constant for the name of the index location attribute. >+ * >+ * The value for this attribute has to be the string representation of a URL. >+ * It should point to an existing index file in a folder or a jar. The URL can also be of platform protocol. >+ * >+ * @since 3.8 >+ */ >+ String INDEX_LOCATION_ATTRIBUTE_NAME = "index_location"; >+</pre> >+</li> >+<li>New API org.eclipse.jdt.core.index.JavaIndexer.generateIndexForJar to generate the index file for a given jar >+<pre> >+ /** >+ * Generates the index file for the specified jar. >+ * >+ * @param pathToJar The full path to the jar that needs to be indexed >+ * @param pathToIndexFile The full path to the index file that needs to be generated >+ * @throws IOException if the jar is not found or could not write into the index file >+ * @since 3.8 >+ */ >+ public static void generateIndexForJar(String pathToJar, String pathToIndexFile) throws IOException; >+</pre> >+</li> >+<li> New application org.eclipse.jdt.core.JavaIndexer to generate index file for the given jar >+</li> >+<li> New ant task eclipse.buildJarIndex to generate the index file for the given jar </li> >+</ul> >+<h3>Problem Reports Fixed</h3> >+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=356620">356620</a> >+Make it possible to provide indexes for defined libraries >+ >+<a name="v_C24"></a> >+<hr><h1> >+Eclipse Platform Build Notes<br> >+Java development tools core</h1> >+Eclipse SDK 3.8.0 - December 5, 2011 - 3.8.1 M4 >+ >+<h2>What's new in this drop</h2> >+ >+<h3>Problem Reports Fixed</h3> >+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365566">365566</a> >+set resource leak diagnostic to "ignore" until bug 358903 is fixed >+ >+<a name="v_C23"></a> >+<hr><h1> >+Eclipse Platform Build Notes<br> >+Java development tools core</h1> >+Eclipse SDK 3.8.0 >+<h2>What's new in this drop</h2> >+<ul> >+<li>New Javacore option org.eclipse.jdt.core.JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS (see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=186342">186342</a> for details): >+<pre> >+ /** >+ * Compiler option ID: Annotation-based Null Analysis. >+ * >+ * This option controls whether the compiler will use null annotations for >+ * improved analysis of (potential) null references. >+ * >+ * When enabled, the compiler will interpret the annotation types defined using >+ * {@link #COMPILER_NONNULL_ANNOTATION_NAME} and {@link #COMPILER_NULLABLE_ANNOTATION_NAME} >+ * as specifying whether or not a given type includes the value <code>null</code>. >+ * >+ * The effect of these analyses is further controlled by the options >+ * {@link #COMPILER_PB_NULL_SPECIFICATION_VIOLATION}, >+ * {@link #COMPILER_PB_POTENTIAL_NULL_SPECIFICATION_VIOLATION} and >+ * {@link #COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO}. >+ * >+ * Option id: <code>"org.eclipse.jdt.core.compiler.annotation.nullanalysis"</code> >+ * Possible values: <code>{ "disabled", "enabled" }</code> >+ * Default: <code>"disabled"</code> >+ * @since 3.8 >+ * @category CompilerOptionID >+ */ >+ public static final String COMPILER_ANNOTATION_NULL_ANALYSIS = PLUGIN_ID + ".compiler.annotation.nullanalysis"; >+</pre></li> >+<li>New Javacore option org.eclipse.jdt.core.JavaCore.COMPILER_NULLABLE_ANNOTATION_NAME (see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=186342">186342</a> for details): >+<pre> >+ /** >+ * Compiler option ID: Name of Annotation Type for Nullable Types. >+ * >+ * This option defines a fully qualified Java type name that the compiler may use >+ * to perform special null analysis. >+ * >+ * If the annotation specified by this option is applied to a type in a method >+ * signature or variable declaration, this will be interpreted as a specification >+ * that <code>null</code> is a legal value in that position. Currently supported >+ * positions are: method parameters, method return type and local variables. >+ * >+ * If a value whose type >+ * is annotated with this annotation is dereferenced without checking for null, >+ * the compiler will trigger a diagnostic as further controlled by >+ * {@link #COMPILER_PB_POTENTIAL_NULL_REFERENCE}. >+ * >+ * The compiler may furthermore check adherence to the null specification as >+ * further controlled by {@link #COMPILER_PB_NULL_SPECIFICATION_VIOLATION}, >+ * {@link #COMPILER_PB_POTENTIAL_NULL_SPECIFICATION_VIOLATION} and >+ * {@link #COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO}. >+ * >+ * This option only has an effect if the the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled. >+ * >+ * Option id: <code>"org.eclipse.jdt.core.compiler.annotation.nullable"</code> >+ * Possible values: any legal, fully qualified Java type name; must resolve to an annotation type. >+ * Default: <code>"org.eclipse.jdt.annotation.Nullable"</code> >+ * @since 3.8 >+ * @category CompilerOptionID >+ */ >+ public static final String COMPILER_NULLABLE_ANNOTATION_NAME = PLUGIN_ID + ".compiler.annotation.nullable"; >+</pre></li> >+<li>New Javacore option org.eclipse.jdt.core.JavaCore.COMPILER_NONNULL_ANNOTATION_NAME (see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=186342">186342</a> for details): >+<pre> >+ /** >+ * Compiler option ID: Name of Annotation Type for Non-Null Types. >+ * >+ * This option defines a fully qualified Java type name that the compiler may use >+ * to perform special null analysis. >+ * >+ * If the annotation specified by this option is applied to a type in a method >+ * signature or variable declaration, this will be interpreted as a specification >+ * that <code>null</code> is <b>not</b> a legal value in that position. Currently >+ * supported positions are: method parameters, method return type and local variables. >+ * >+ * For values declared with this annotation, the compiler will never trigger a null >+ * reference diagnostic (as controlled by {@link #COMPILER_PB_POTENTIAL_NULL_REFERENCE} >+ * and {@link #COMPILER_PB_NULL_REFERENCE}), because the assumption is made that null >+ * will never occur at runtime in these positions. >+ * >+ * The compiler may furthermore check adherence to the null specification as further >+ * controlled by {@link #COMPILER_PB_NULL_SPECIFICATION_VIOLATION}, >+ * {@link #COMPILER_PB_POTENTIAL_NULL_SPECIFICATION_VIOLATION} and >+ * {@link #COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO}. >+ * >+ * This option only has an effect if the the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled. >+ * >+ * Option id: <code>"org.eclipse.jdt.core.compiler.annotation.nonnull"</code> >+ * Possible values: any legal, fully qualified Java type name; must resolve to an annotation type. >+ * Default: <code>"org.eclipse.jdt.annotation.NonNull"</code> >+ * @since 3.8 >+ * @category CompilerOptionID >+ */ >+ public static final String COMPILER_NONNULL_ANNOTATION_NAME = PLUGIN_ID + ".compiler.annotation.nonnull"; >+</pre></li> >+<li>New Javacore option org.eclipse.jdt.core.JavaCore.COMPILER_NONNULL_BY_DEFAULT_ANNOTATION_NAME (see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=186342">186342</a> for details): >+<pre> >+ /** >+ * Compiler option ID: Name of Annotation Type to specify a nullness default for unannotated types. >+ * >+ * This option defines a fully qualified Java type name that the compiler may use >+ * to perform special null analysis. >+ * >+ * If the annotation is applied without an argument, all unannotated types in method signatures >+ * within the annotated element will be treated as if they were specified with the non-null annotation >+ * (see {@link #COMPILER_NONNULL_ANNOTATION_NAME}). >+ * >+ * If the annotation is applied with the constant <code>false</code> as its argument >+ * all corresponding defaults at outer scopes will be canceled for the annotated element. >+ * This includes defaults specified using this annotation type or a default defined using >+ * the compiler option {@link #COMPILER_NONNULL_IS_DEFAULT}. >+ * >+ * This option only has an effect if the the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled. >+ * >+ * Option id: <code>"org.eclipse.jdt.core.compiler.annotation.nonnullbydefault"</code> >+ * Possible values: any legal, fully qualified Java type name; must resolve to an annotation type. >+ * That annotation type should have exactly one boolean parameter. >+ * Default: <code>"org.eclipse.jdt.annotation.NonNullByDefault"</code> >+ * @since 3.8 >+ * @category CompilerOptionID >+ */ >+ public static final String COMPILER_NONNULL_BY_DEFAULT_ANNOTATION_NAME = PLUGIN_ID + ".compiler.annotation.nonnullbydefault"; >+</pre></li> >+<li>New Javacore option org.eclipse.jdt.core.JavaCore.COMPILER_NONNULL_IS_DEFAULT (see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=186342">186342</a> for details): >+<pre> >+ /** >+ * Compiler option ID: Globally specify non-null as the assumed default for unannotated types. >+ * >+ * When enabled this option globally achieves the same effect >+ * as specifying {@link #COMPILER_NONNULL_ANNOTATION_NAME} does for individual elements. >+ * >+ * This option only has an effect if the the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled. >+ * >+ * Option id: <code>"org.eclipse.jdt.core.compiler.annotation.nonnullisdefault"</code> >+ * Possible values: <code>{ "disabled", "enabled" }</code>. >+ * Default: <code>"disabled"</code> >+ * @since 3.8 >+ * @category CompilerOptionID >+ */ >+ public static final String COMPILER_NONNULL_IS_DEFAULT = PLUGIN_ID + ".compiler.annotation.nonnullisdefault"; >+</pre></li> >+<li>New Javacore option org.eclipse.jdt.core.JavaCore.COMPILER_PB_NULL_SPECIFICATION_VIOLATION (see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=186342">186342</a> for details): >+<pre> >+ /** >+ * Compiler option ID: Reporting Violations of Null Specifications. >+ * >+ * Depending on this option, the compiler will issue either an error or a warning >+ * whenever one of the following situations is detected: >+ * >+ * 1. A method declared with a nonnull annotation returns an expression that is >+ * statically known to evaluate to a null value. >+ * 2. An expression that is statically known to evaluate to a null value is passed >+ * as an argument in a method call where the corresponding parameter of the called >+ * method is declared with a nonnull annotation. >+ * 3. An expression that is statically known to evaluate to a null value is assigned >+ * to a local variable that is declared with a nonnull annotation. >+ * 4. A method that overrides an inherited method declared with a nonnull annotation >+ * tries to relax that contract by specifying a nullable annotation >+ * (prohibition of contravariant return). >+ * 5. A method that overrides an inherited method which has a nullable declaration >+ * for at least one of its parameters, tries to tighten that null contract by >+ * specifying a nonnull annotation for its corresponding parameter >+ * (prohibition of covariant parameters). >+ * >+ * The compiler options {@link #COMPILER_NONNULL_ANNOTATION_NAME} and >+ * {@link #COMPILER_NULLABLE_ANNOTATION_NAME} control which annotations the compiler >+ * shall interpret as nonnull or nullable annotations, respectively. >+ * >+ * This option only has an effect if the the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled. >+ * >+ * Option id: <code>"org.eclipse.jdt.core.compiler.problem.nullSpecViolation"</code> >+ * Possible values: <code>{ "error", "warning" }</code> >+ * Default: <code>"error"</code> >+ * >+ * @since 3.8 >+ * @category CompilerOptionID >+ */ >+ public static final String COMPILER_PB_NULL_SPECIFICATION_VIOLATION = PLUGIN_ID + ".compiler.problem.nullSpecViolation"; >+</pre></li> >+<li>New Javacore option org.eclipse.jdt.core.JavaCore.COMPILER_PB_POTENTIAL_NULL_SPECIFICATION_VIOLATION (see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=186342">186342</a> for details): >+<pre> >+ /** >+ * Compiler option ID: Reporting Violations of Null Specifications with Potential Null Value. >+ * >+ * When enabled, the compiler will issue an error or a warning whenever one of the >+ * following situations is detected: >+ * >+ * 1. A method declared with a nonnull annotation returns an expression that is >+ * statically known to evaluate to a null value on some flow. >+ * 2. An expression that is statically known to evaluate to a null value on some flow >+ * is passed as an argument in a method call where the corresponding parameter of >+ * the called method is declared with a nonnull annotation. >+ * 3. An expression that is statically known to evaluate to a null value on some flow >+ * is assigned to a local variable that is declared with a nonnull annotation. >+ * >+ * The compiler options {@link #COMPILER_NONNULL_ANNOTATION_NAME} and >+ * {@link #COMPILER_NULLABLE_ANNOTATION_NAME} control which annotations the compiler >+ * shall interpret as nonnull or nullable annotations, respectively. >+ * >+ * >+ * This option only has an effect if the the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled. >+ * >+ * Option id: <code>"org.eclipse.jdt.core.compiler.problem.potentialNullSpecViolation"</code> >+ * Possible values: <code>{ "error", "warning", "ignore" }</code> >+ * Default: <code>"error"</code> >+ * >+ * @since 3.8 >+ * @category CompilerOptionID >+ */ >+ public static final String COMPILER_PB_POTENTIAL_NULL_SPECIFICATION_VIOLATION = PLUGIN_ID + ".compiler.problem.potentialNullSpecViolation"; >+</pre></li> >+<li>New Javacore option org.eclipse.jdt.core.JavaCore.COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO (see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=186342">186342</a> for details): >+<pre> >+ /** >+ * Compiler option ID: Reporting Insufficient Information for Analysing Adherence to Null Specifications. >+ * >+ * When enabled, the compiler will issue an error or a warning whenever one of the >+ * following situations is detected: >+ * >+ * 1. A method declared with a nonnull annotation returns an expression for which >+ * insufficient nullness information is available for statically proving that no >+ * flow will pass a null value at runtime. >+ * 2. An expression for which insufficient nullness information is available for >+ * statically proving that it will never evaluate to a null value at runtime >+ * is passed as an argument in a method call where the corresponding parameter of >+ * the called method is declared with a nonnull annotation. >+ * 3. An expression for which insufficient nullness information is available for >+ * statically proving that it will never evaluate to a null value at runtime >+ * is assigned to a local variable that is declared with a nonnull annotation. >+ * >+ * Insufficient nullness information is usually a consequence of using other unannotated >+ * variables or methods. >+ * >+ * The compiler options {@link #COMPILER_NONNULL_ANNOTATION_NAME} and >+ * {@link #COMPILER_NULLABLE_ANNOTATION_NAME} control which annotations the compiler >+ * shall interpret as nonnull or nullable annotations, respectively. >+ * >+ * This option only has an effect if the the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled. >+ * >+ * Option id: <code>"org.eclipse.jdt.core.compiler.problem.nullSpecInsufficientInfo"</code> >+ * Possible values: <code>{ "error", "warning", "ignore" }</code> >+ * Default: <code>"warning"</code> >+ * >+ * @since 3.8 >+ * @category CompilerOptionID >+ */ >+ public static final String COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO = PLUGIN_ID + ".compiler.problem.nullSpecInsufficientInfo"; >+</pre></li> >+<li>New Javacore option org.eclipse.jdt.core.JavaCore.COMPILER_PB_REDUNDANT_NULL_ANNOTATION (see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=186342">186342</a> for details): >+<pre> >+ /** >+ * Compiler option ID: Reporting Redundant Null Annotations. >+ * >+ * When enabled, the compiler will issue an error or a warning when a non-null annotation >+ * (see {@link #COMPILER_NONNULL_ANNOTATION_NAME}) >+ * is applied although the same effect is already achieved by a default applicable at the >+ * current location. Such a default may be effective by enabling the option >+ * {@link #COMPILER_NONNULL_IS_DEFAULT} or by using the annotation specified by the option >+ * {@link #COMPILER_NONNULL_BY_DEFAULT_ANNOTATION_NAME}. >+ * >+ * This option only has an effect if the the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled. >+ * >+ * Option id: <code>"org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation"</code> >+ * Possible values: <code>{ "error", "warning", "ignore" }</code> >+ * Default: <code>"warning"</code> >+ * >+ * @since 3.8 >+ * @category CompilerOptionID >+ */ >+ public static final String COMPILER_PB_REDUNDANT_NULL_ANNOTATION = PLUGIN_ID + ".compiler.problem.redundantNullAnnotation"; >+</pre> >+</li> >+<li>New API added to org.eclipse.jdt.core.compiler.IProblem to signal null-related issues: >+ <ul> >+ <li> int RequiredNonNullButProvidedNull</li> >+ <li> int RequiredNonNullButProvidedPotentialNull</li> >+ <li> int RequiredNonNullButProvidedUnknown</li> >+ <li> int MissingNullAnnotationType</li> >+ <li> int IllegalReturnNullityRedefinition</li> >+ <li> int IllegalRedefinitionToNonNullParameter</li> >+ <li> int IllegalDefinitionToNonNullParameter</li> >+ <li> int ParameterLackingNonNullAnnotation</li> >+ <li> int ParameterLackingNullableAnnotation</li> >+ <li> int PotentialNullMessageSendReference</li> >+ <li> int RedundantNullCheckOnNonNullMessageSend</li> >+ <li> int CannotImplementIncompatibleNullness</li> >+ <li> int RedundantNullAnnotation</li> >+ <li> int IllegalAnnotationForBaseType</li> >+ </ul> >+</ul> >+ >+<h3>Problem Reports Fixed</h3> >+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=363858">363858</a> >+[dom] early throwing of AbortCompilation causes NPE in CompilationUnitResolver >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=331647">331647</a> >+[compiler][null] support flexible default mechanism for null-annotations >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=334457">334457</a> >+[compiler][null] check compatibility of inherited null contracts >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=186342">186342</a> >+[compiler][null] Using annotations for null checking >+ >+<hr><h1> >+Eclipse Platform Build Notes<br> >+Java development tools core</h1> >+Eclipse SDK 3.8.0 - November 29, 2011 >+<h2>What's new in this drop</h2> >+ >+<h3>Problem Reports Fixed</h3> >+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340945">340945</a> >+Extension Request of JavaContentAssistInvocationContext >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=364672">364672</a> >+[compiler] ecj fails to compile valid calls to varargs method >+ >+<a name="v_C21"></a> >+<hr><h1> >+Eclipse Platform Build Notes<br> >+Java development tools core</h1> >+Eclipse SDK 3.8.0 - November 22, 2011 >+<h2>What's new in this drop</h2> >+ >+<h3>Problem Reports Fixed</h3> >+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=350738">350738</a> >+"The method is never used locally" is not shown for parameterized recursive methods >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=361053">361053</a> >+java.lang.VerifyError on try-with-resources >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=346038">346038</a> >+[1.5][compiler] ecj vs. javac differ for methods using vararg parameters of different primitive types >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=346039">346039</a> >+[1.5][compiler] ecj vs. javac differ for varargs overloading >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=362279">362279</a> >+ecj vs. javac differ for automatic boxing of implicitly converted types >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=362591">362591</a> >+VerifyError: Inconsistent stackmap frames >+ >+<a name="v_C20"></a> >+<hr><h1> >+Eclipse Platform Build Notes<br> >+Java development tools core</h1> >+Eclipse SDK 3.8.0 - November 15, 2011 >+<br>Project org.eclipse.jdt.core v_C20 >+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_C20">cvs</a>). >+<h2>What's new in this drop</h2> >+ >+<h3>Problem Reports Fixed</h3> >+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=361327">361327</a> >+Static import resolution does not record all static elements being imported >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=346042">346042</a> >+[1.5][compiler] ecj compiles code rejected by javac for varargs parameters of inaccessible type >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=361938">361938</a> >+Formerly working JLS3 parser not working -- Scanner reports com.sun.jdi.InvocationException occurred invoking method. >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359284">359284</a> >+Unnecessary checkast from null >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=361441">361441</a> >+Error in JDT Core during AST creation >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=363293">363293</a> >+resource leaks in org.eclipse.jdt.compiler.tool.tests >+ >+<a name="v_C19"></a> >+<hr><h1> >+Eclipse Platform Build Notes<br> >+Java development tools core</h1> >+Eclipse SDK 3.8.0 - November 8, 2011 >+<br>Project org.eclipse.jdt.core v_C19 >+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_C19">cvs</a>). >+<h2>What's new in this drop</h2> >+ >+<h3>Problem Reports Fixed</h3> >+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=361922">361922</a> >+Fup of 357425: ensure all reported regressions are witnessed by tests >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=354766">354766</a> >+Javadoc content does not appear in content assist info window for non-static inner class constructors >+ >+<a name="v_C18"></a> >+<hr><h1> >+Eclipse Platform Build Notes<br> >+Java development tools core</h1> >+Eclipse SDK 3.8.0 - October 25, 2011 - 3.8.0 M3 >+<br>Project org.eclipse.jdt.core v_C18 >+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_C18">cvs</a>). >+<h2>What's new in this drop</h2> >+ >+<h3>Problem Reports Fixed</h3> >+ >+<a name="v_C17"></a> >+<hr><h1> >+Eclipse Platform Build Notes<br> >+Java development tools core</h1> >+Eclipse SDK 3.8.0 - October 20, 2011 >+<br>Project org.eclipse.jdt.core v_C17 >+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_C17">cvs</a>). >+<h2>What's new in this drop</h2> >+<ul> >+<li>Added a new API OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE(see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=287164">287164</a> for details): >+<pre> >+/** >+ * Status constant indicating that the default or specific output folder is overlapping >+ * with another source location. >+ * @since 3.8 >+ */ >+public static final int OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE = 1013; >+</pre> >+</li> >+ >+<li>Added a new option CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE to report an output location overlapping another source location(see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=287164">287164</a> for details): >+<pre> >+/** >+ * Core option ID: Reporting an output location overlapping another source location. >+ * Indicate the severity of the problem reported when a source entry's output location overlaps another >+ * source entry. >+ * >+ * Option id:"org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource" >+ * Possible values:{ "error", "warning", "ignore" } >+ * Default:"error" >+ * >+ * @since 3.8 >+ */ >+public static final String CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE = PLUGIN_ID + ".classpath.outputOverlappingAnotherSource"; >+</pre> >+</li> >+</ul> >+<h3>Problem Reports Fixed</h3> >+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=287164">287164</a> >+Report build path error if source folder has other source folder as output folder >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359721">359721</a> >+[options] add command line option for new warning token "resource" >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=343480">343480</a> >+[compiler] Incorrect/confusing error message on inner class static field declaration >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=318401">318401</a> >+FUP of 317858: Clarify eclipse compiler behavior on imports & shadowing >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=360317">360317</a> >+[compiler] report switch over enum in 1.4- mode >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=360164">360164</a> >+Compile error in XSDImpl >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359727">359727</a> >+[1.7][doc] Update doc for new resource leak warnings >+ >+<a name="v_C16"></a> >+<hr><h1> >+Eclipse Platform Build Notes<br> >+Java development tools core</h1> >+Eclipse SDK 3.8.0 - October 18, 2011 >+<br>Project org.eclipse.jdt.core v_C16 >+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_C16">cvs</a>). >+<h2>What's new in this drop</h2> >+<ul> >+<li>Added a new API IBootstrapMethodsEntry to describe the bootstrap method table entry(see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359943">359943</a> for details): >+<pre> >+/** >+ * Description of a bootstrap method table entry as specified in the JVM specifications. >+ * >+ * This interface may be implemented by clients. >+ * >+ * @since 3.8 >+ */ >+public interface IBootstrapMethodsEntry; >+</pre> >+</li> >+ >+<li>Added a new API IBootstrapMethodsAttribute to describe the bootstrap method attribute(see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359943">359943</a> for details): >+<pre> >+/** >+ * Description of a bootstrap methods attribute as described in the JVM specifications. >+ * >+ * This interface may be implemented by clients. >+ * >+ * @since 3.8 >+ */ >+public interface IBootstrapMethodsAttribute >+</pre> >+</li> >+ >+<li>Added a new API in IBootstrapMethodsAttribute to obtain the number of bootstrap methods of this entry(see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359943">359943</a> for details): >+<pre> >+/** >+ * Answer back the number of bootstrap methods of this entry as specified in >+ * the JVM specifications. >+ * >+ * @return the number of bootstrap methods of this entry as specified in >+ * the JVM specifications >+ */ >+int getBootstrapMethodsLength(); >+</pre> >+</li> >+ >+<li>Added a new API in IBootstrapMethodsAttribute to obtain the bootstrap methods table of this entry(see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359943">359943</a> for details): >+<pre> >+/** >+ * Answer back the bootstrap methods table of this entry as specified in >+ * the JVM specifications. Answer an empty array if none. >+ * >+ * @return the bootstrap methods table of this entry as specified in >+ * the JVM specifications. Answer an empty array if none >+ */ >+IBootstrapMethodsEntry[] getBootstrapMethods(); >+</pre> >+</li> >+ >+<li>Added IConstantPoolEntry2 to describe the new constant pool entry from Java 7 onwards(see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359943">359943</a> for details): >+<pre> >+/** >+ * Description of the new constant pool entry as described in the JVM specifications >+ * added for Java 7 support. >+ * Its contents is initialized according to its kind. >+ * >+ * This interface may be implemented by clients. >+ * >+ * @since 3.8 >+ */ >+public interface IConstantPoolEntry2 >+</pre> >+</li> >+ >+<li>Added new API in IConstantPoolEntry2 to return the descriptor index for MethodType entry(see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359943">359943</a> for details): >+<pre> >+/** >+ * Returns the descriptor index. This value is set only when decoding a MethodType entry. >+ * The value is unspecified otherwise. The corresponding UTF8 value can be retrieved by using >+ * {@link #getMethodDescriptor()}. >+ * >+ * @return the descriptor index. This value is set only when decoding a MethodType entry. >+ * @see IConstantPoolConstant#CONSTANT_MethodType >+ */ >+int getDescriptorIndex(); >+</pre> >+</li> >+ >+<li>Added new API in IConstantPoolEntry2 to return the reference kind for MethodHandle entry(see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359943">359943</a> for details): >+<pre> >+/** >+ * Returns the reference kind. This value is set only when decoding a MethodHandle entry. >+ * The value is unspecified otherwise. >+ * >+ * @return the reference kind. This value is set only when decoding a MethodHandle entry. >+ * @see IConstantPoolConstant#CONSTANT_MethodHandle >+ */ >+int getReferenceKind(); >+</pre> >+</li> >+ >+<li>Added new API in IConstantPoolEntry2 to return the reference index for MethodHandle entry(see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359943">359943</a> for details): >+<pre> >+/** >+ * Returns the reference index. This value is set only when decoding a MethodHandle entry. >+ * The value is unspecified otherwise. >+ * >+ * @return the reference kind. This value is set only when decoding a MethodHandle entry. >+ * @see IConstantPoolConstant#CONSTANT_MethodHandle >+ */ >+int getReferenceIndex(); >+</pre> >+</li> >+ >+<li>Added new API in IConstantPoolEntry2 to return the bootstrap method attribute index(see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359943">359943</a> for details): >+<pre> >+/** >+ * Returns the bootstrap method attribute index. This value is set only when decoding a InvokeDynamic entry. >+ * The value is unspecified otherwise. >+ * >+ * @return the reference kind. This value is set only when decoding a MethodHandle entry. >+ * @see IConstantPoolConstant#CONSTANT_InvokeDynamic >+ */ >+int getBootstrapMethodAttributeIndex(); >+</pre> >+</li> >+ >+<li>Added new API in IByteCodeVisitor(see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359943">359943</a> for details): >+<pre> >+ /** >+ * @since 3.8 >+ */ >+ void _invokedynamic( >+ int pc, >+ int index, >+ IConstantPoolEntry invokeDynamic); >+</pre> >+<p> >+This has been added in place of the deprecated API >+<pre> >+ void _invokedynamic( >+ int pc, >+ int index, >+ IConstantPoolEntry nameEntry, >+ IConstantPoolEntry descriptorEntry); >+</pre> >+</li> >+</ul> >+<h3>Problem Reports Fixed</h3> >+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359943">359943</a> >+invokedynamic in generated class file is not correctly recognized by the eclipse compiler >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=360644">360644</a> >+Scope.isDefinedInSameUnit(ReferenceBinding) fails for a ParameterizedTypeBinding >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=358762">358762</a> >+NPE in JDT compiler >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=360328">360328</a> >+[compiler][null] detect null problems in nested code (local class inside a loop) >+ >+<a name="v_C15"></a> >+<hr><h1> >+Eclipse Platform Build Notes<br> >+Java development tools core</h1> >+Eclipse SDK 3.8.0 - October 11, 2011 >+<br>Project org.eclipse.jdt.core v_C15 >+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_C15">cvs</a>). >+<h2>What's new in this drop</h2> >+ >+<h3>Problem Reports Fixed</h3> >+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=350285">350285</a> >+ASTRewrite destroys formatting on CatchClause#setBody(copyTarget) >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=353474">353474</a> >+type converters should include more annotations >+ >+<a name="v_C14"></a> >+<hr><h1> >+Eclipse Platform Build Notes<br> >+Java development tools core</h1> >+Eclipse SDK 3.8.0 - October 5, 2011 >+<br>Project org.eclipse.jdt.core v_C14 >+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_C14">cvs</a>). >+<h2>What's new in this drop</h2> >+ >+<h3>Problem Reports Fixed</h3> >+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=354181">354181</a> >+migrate jdt.core to git >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359831">359831</a> >+Fix messages for "new warning for missing try-with-resources" >+ >+<a name="v_C13"></a> >+<hr><h1> >+Eclipse Platform Build Notes<br> >+Java development tools core</h1> >+Eclipse SDK 3.8.0 - October 3, 2011 >+<br>Project org.eclipse.jdt.core v_C13 >+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_C13">cvs</a>). >+<h2>What's new in this drop</h2> >+<ul> >+<li>New Javacore option org.eclipse.jdt.core.JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE to raise a warning or error >+ when a resource of type Closeable or AutoCloseable is not closed locally. >+(see details in bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=349326">349326</a>): >+<pre> >+ /** >+ * Compiler option ID: Reporting a resource that is not closed properly. >+ * >+ * When enabled, the compiler will issue an error or a warning if >+ * a local variable holds a value of type <code>java.lang.AutoCloseable</code> (compliance>=1.7) >+ * or a value of type <code>java.io.Closeable</code> (compliance<=1.6) and if >+ * flow analysis shows that the method <code>close()</code> is not invoked locally on that value. >+ * >+ * Option id: <code>"org.eclipse.jdt.core.compiler.problem.reportUnclosedCloseable"</code> >+ * Possible values: <code>{ "error", "warning", "ignore" }</code> >+ * Default: <code>"warning"</code> >+ * >+ * @since 3.8 >+ * @category CompilerOptionID >+ */ >+ public static final String COMPILER_PB_UNCLOSED_CLOSEABLE = PLUGIN_ID + ".compiler.problem.unclosedCloseable"; //$NON-NLS-1$ >+</pre> >+</li> >+<li>New Javacore option org.eclipse.jdt.core.JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE to raise a warning or error >+ when a resource of type Closeable or AutoCloseable is not definitely closed locally. >+(see details in bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=349326">349326</a>): >+<pre> >+ /** >+ * Compiler option ID: Reporting a resource that may not be closed properly. >+ * >+ * When enabled, the compiler will issue an error or a warning if >+ * a local variable holds a value of type <code>java.lang.AutoCloseable</code> (compliance>=1.7) >+ * or a value of type <code>java.io.Closeable</code> (compliance<=1.6) and if >+ * flow analysis shows that the method <code>close()</code> is >+ * not invoked locally on that value for all execution paths. >+ * >+ * Option id: <code>"org.eclipse.jdt.core.compiler.problem.reportPotentiallyUnclosedCloseable"</code> >+ * Possible values: <code>{ "error", "warning", "ignore" }</code> >+ * Default: <code>"ignore"</code> >+ * >+ * @since 3.8 >+ * @category CompilerOptionID >+ */ >+ public static final String COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE = PLUGIN_ID + ".compiler.problem.potentiallyUnclosedCloseable"; //$NON-NLS-1$ >+</pre> >+</li> >+<li>New Javacore option org.eclipse.jdt.core.JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE to raise a warning or error >+ when a resource of type AutoCloseable is closed explicitly rather than using a try-with-resources block. >+(see details in bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=349326">349326</a>): >+<pre> >+ /** >+ * Compiler option ID: Reporting a resource that is not managed by try-with-resources. >+ * >+ * When enabled, the compiler will issue an error or a warning if a local variable >+ * holds a value of type <code>java.lang.AutoCloseable</code>, and if the method >+ * <code>close()</code> is explicitly invoked on that resource, but the resource is >+ * not managed by a try-with-resources block. >+ * >+ * Option id: <code>"org.eclipse.jdt.core.compiler.problem.reportPotentiallyUnclosedCloseable"</code> >+ * Possible values: <code>{ "error", "warning", "ignore" }</code> >+ * Default: <code>"ignore"</code> >+ * >+ * @since 3.8 >+ * @category CompilerOptionID >+ */ >+ public static final String COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE = PLUGIN_ID + ".compiler.problem.explicitlyClosedAutoCloseable"; //$NON-NLS-1$ >+</pre> >+</li> >+</ul> >+ >+<h3>Problem Reports Fixed</h3> >+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359495">359495</a> >+[1.7][compiler] VerifyError in try-finally block with lock encompassing for-each block and unlock in finally clause >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=161129">161129</a> >+[batch][compiler] Add -warn:all to report all warnings >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359646">359646</a> >+Formatter fails silently if Java source contains 0x8000000000000000L >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=256796">256796</a> >+[compiler] dead code detection: "if (DEBUG) return;" should also be trivial IF stmt >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359334">359334</a> >+Analysis for resource leak warnings does not consider exceptions as method exit points >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359362">359362</a> >+FUP of bug 349326: Resource leak on non-Closeable resource. >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=348186">348186</a> >+[compiler] Improve wording for the warning for masked/hidden catch block >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=355838">355838</a> >+[compiler] ecj compiles the code that javac6 rejects >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=349326">349326</a> >+[1.7] new warning for missing try-with-resources >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=354502">354502</a> >+Incorrect Compiler Warning: "Method can be declared as static" >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=241834">241834</a> >+[search] ClassCastException during move class refactoring >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=358827">358827</a> >+[1.7] exception analysis for t-w-r spoils null analysis >+ >+<a name="v_C12"></a> >+<hr><h1> >+Eclipse Platform Build Notes<br> >+Java development tools core</h1> >+Eclipse SDK 3.8.0 - September 23, 2011 >+<br>Project org.eclipse.jdt.core v_C12 >+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_C12">cvs</a>). >+<h2>What's new in this drop</h2> >+<ul> >+<li>Tagging to prepare for the git migration</li> >+</ul> >+ >+<h3>Problem Reports Fixed</h3> >+ >+<a name="v_C11"></a> >+<hr><h1> >+Eclipse Platform Build Notes<br> >+Java development tools core</h1> >+Eclipse SDK 3.8.0 - September 20, 2011 >+<br>Project org.eclipse.jdt.core v_C11 >+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_C11">cvs</a>). >+<h2>What's new in this drop</h2> >+ >+<h3>Problem Reports Fixed</h3> >+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=357110">357110</a> >+Problem with inner classes referenced from jars or class folders: "The type ... cannot be resolved" >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=357471">357471</a> >+ASTParser cannot resolve binding of PackageDeclaration if class name is equal to the first segment of the package name >+ >+<a name="v_C10"></a> >+<hr><h1> >+Eclipse Platform Build Notes<br> >+Java development tools core</h1> >+Eclipse SDK 3.8.0 - September 13, 2011 - 3.8.0 M2 >+<br>Project org.eclipse.jdt.core v_C10 >+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_C10">cvs</a>). >+<h2>What's new in this drop</h2> >+ >+<h3>Problem Reports Fixed</h3> >+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=357259">357259</a> >+[dom] AST#newArrayType(Type, int) should allow array type as argument >+ >+<a name="v_C09"></a> >+<hr><h1> >+Eclipse Platform Build Notes<br> >+Java development tools core</h1> >+Eclipse SDK 3.8.0 - September 9, 2011 >+<br>Project org.eclipse.jdt.core v_C09 >+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_C09">cvs</a>). >+<h2>What's new in this drop</h2> >+ >+<h3>Problem Reports Fixed</h3> >+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=354332">354332</a> >+DeltaProcessor exhibits O(N^2) behavior >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=355605">355605</a> >+NPE in HierarchyResolver >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=347396">347396</a> >+ASTParser returns empty or partial AST if we parse the the body contains empty for loop >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=356746">356746</a> >+ECJ accepts illegal unicode escape sequences >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=337935">337935</a> >+Test failures when run as an IDE (org.eclipse.sdk.ide) >+ > <a name="v_C08"></a> > <hr><h1> > Eclipse Platform Build Notes<br> > Java development tools core</h1> >-Eclipse SDK 3.8.0 - %date% - 3.8.0 M2 >+Eclipse SDK 3.8.0 - September 6, 2011 > <br>Project org.eclipse.jdt.core v_C08 > (<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_C08">cvs</a>). > <h2>What's new in this drop</h2> > > <h3>Problem Reports Fixed</h3> >-<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=24804">24804</a> >+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=356325">356325</a> >+[select] Open declaration on a constructor of a local class with type parameters doesn't work >+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=24804">24804</a> > Organize imports wipes comments between statements [code manipulation] > <br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=356363">356363</a> > Many links to java.sun.com are broken >@@ -143,7 +1247,6 @@ > * Returns the binding key of the declaring type of the element represented by this binding key. If the binding key > * does not represent a member or if the member doesn't have a declaring type, returns <code>null</code>. > * >- * <p> > * Note that only binding keys for references to methods and fields > * are fully supported. The binding keys for declarations will not have type parameters. > * >@@ -208,7 +1311,7 @@ > <li>Added a new API in CompletionProposal to tell whether it diamond operator can be used (see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=351444">351444</a> for details): > <pre> > /** >- * Returns whether it is safe to use the '<>' (diamond) operator in place of explicitly specifying >+ * Returns whether it is safe to use the '<>' (diamond) operator in place of explicitly specifying > * type arguments for this proposal. > * > * This is only relevant for source level 1.7 or greater. >@@ -227,7 +1330,7 @@ > /** > * Compiler option ID: Reporting redundant specification of type arguments in class instance creation expressions. > * When enabled, the compiler will issue an error or a warning if type arguments are used in a class instance creation, >- * when the '<>' operator can be used instead. >+ * when the '<>' operator can be used instead. > * > * This option only has an effect if the compiler compliance is 1.7 or greater. > * >diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java >index 8b7c565..989c11c 100644 >--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java >+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java >@@ -1502,6 +1502,7 @@ > this.lookupEnvironment, > scope, > astNode, >+ astNodeParent, > this.owner, > this.parser); > } >diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalCompletionContext.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalCompletionContext.java >index ba33ea1..bba8d78 100644 >--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalCompletionContext.java >+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalCompletionContext.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2005, 2008 IBM Corporation and others. >+ * Copyright (c) 2005, 2011 IBM Corporation 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 >@@ -24,8 +24,12 @@ > import org.eclipse.jdt.internal.codeassist.complete.CompletionParser; > import org.eclipse.jdt.internal.compiler.ast.ASTNode; > import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; >+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; >+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding; > import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment; >+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; > import org.eclipse.jdt.internal.compiler.lookup.Scope; >+import org.eclipse.jdt.internal.compiler.util.ObjectVector; > > > /** >@@ -65,6 +69,7 @@ > LookupEnvironment lookupEnvironment, > Scope scope, > ASTNode astNode, >+ ASTNode astNodeParent, > WorkingCopyOwner owner, > CompletionParser parser) { > this.isExtended = true; >@@ -76,6 +81,7 @@ > lookupEnvironment, > scope, > astNode, >+ astNodeParent, > owner, > parser); > } >@@ -368,4 +374,87 @@ > public boolean isInJavadocText() { > return (this.javadoc & CompletionOnJavadoc.TEXT) != 0; > } >+ >+ /** >+ * Return the completion node associated with the current completion. >+ * >+ * @return completion AST node, or null if the extendedContext is null. >+ * @exception UnsupportedOperationException if the context is not an extended context >+ * >+ * @see #isExtended() >+ */ >+ public ASTNode getCompletionNode() { >+ if (!this.isExtended) throw new UnsupportedOperationException("Operation only supported in extended context"); //$NON-NLS-1$ >+ >+ if (this.extendedContext == null) return null; >+ >+ return this.extendedContext.getCompletionNode(); >+ } >+ >+ /** >+ * Return the parent AST node of the completion node associated with the current completion. >+ * >+ * @return completion parent AST node, or null if the extendedContext is null. >+ * @exception UnsupportedOperationException if the context is not an extended context >+ * >+ * @see #isExtended() >+ */ >+ public ASTNode getCompletionNodeParent() { >+ if (!this.isExtended) throw new UnsupportedOperationException("Operation only supported in extended context"); //$NON-NLS-1$ >+ >+ if (this.extendedContext == null) return null; >+ >+ return this.extendedContext.getCompletionNodeParent(); >+ } >+ >+ /** >+ * Return the bindings of all visible local variables in the current completion context. >+ * >+ * @return bindings of all visible local variables, or null if the extendedContext is null. Returned bindings are instances of >+ * {@link LocalVariableBinding} >+ * @exception UnsupportedOperationException if the context is not an extended context >+ * >+ * @see #isExtended() >+ */ >+ public ObjectVector getVisibleLocalVariables() { >+ if (!this.isExtended) throw new UnsupportedOperationException("Operation only supported in extended context"); //$NON-NLS-1$ >+ >+ if (this.extendedContext == null) return null; >+ >+ return this.extendedContext.getVisibleLocalVariables(); >+ } >+ >+ /** >+ * Return the bindings of all visible fields in the current completion context. >+ * >+ * @return bindings of all visible fields, or null if the extendedContext is null. Returned bindings are instances of >+ * {@link FieldBinding} >+ * @exception UnsupportedOperationException if the context is not an extended context >+ * >+ * @see #isExtended() >+ */ >+ public ObjectVector getVisibleFields() { >+ if (!this.isExtended) throw new UnsupportedOperationException("Operation only supported in extended context"); //$NON-NLS-1$ >+ >+ if (this.extendedContext == null) return null; >+ >+ return this.extendedContext.getVisibleFields(); >+ } >+ >+ /** >+ * Return the bindings of all visible methods in the current completion context. >+ * >+ * @return bindings of all visible methods, or null if the extendedContext is null. Returned bindings are instances of >+ * {@link MethodBinding} >+ * @exception UnsupportedOperationException if the context is not an extended context >+ * >+ * @see #isExtended() >+ */ >+ public ObjectVector getVisibleMethods() { >+ if (!this.isExtended) throw new UnsupportedOperationException("Operation only supported in extended context"); //$NON-NLS-1$ >+ >+ if (this.extendedContext == null) return null; >+ >+ return this.extendedContext.getVisibleMethods(); >+ } > } >diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalExtendedCompletionContext.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalExtendedCompletionContext.java >index 152977a..19f2546 100644 >--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalExtendedCompletionContext.java >+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalExtendedCompletionContext.java >@@ -76,6 +76,7 @@ > private LookupEnvironment lookupEnvironment; > private Scope assistScope; > private ASTNode assistNode; >+ private ASTNode assistNodeParent; > private WorkingCopyOwner owner; > > private CompletionParser parser; >@@ -98,6 +99,7 @@ > LookupEnvironment lookupEnvironment, > Scope assistScope, > ASTNode assistNode, >+ ASTNode assistNodeParent, > WorkingCopyOwner owner, > CompletionParser parser) { > this.completionContext = completionContext; >@@ -106,6 +108,7 @@ > this.lookupEnvironment = lookupEnvironment; > this.assistScope = assistScope; > this.assistNode = assistNode; >+ this.assistNodeParent = assistNodeParent; > this.owner = owner; > this.parser = parser; > } >@@ -929,4 +932,40 @@ > } > return false; > } >+ >+ /** >+ * @see InternalCompletionContext#getCompletionNode() >+ */ >+ public ASTNode getCompletionNode() { >+ return this.assistNode; >+ } >+ >+ /** >+ * @see InternalCompletionContext#getCompletionNodeParent() >+ */ >+ public ASTNode getCompletionNodeParent() { >+ // TODO Auto-generated method stub >+ return this.assistNodeParent; >+ } >+ >+ public ObjectVector getVisibleLocalVariables() { >+ if (!this.hasComputedVisibleElementBindings) { >+ computeVisibleElementBindings(); >+ } >+ return this.visibleLocalVariables; >+ } >+ >+ public ObjectVector getVisibleFields() { >+ if (!this.hasComputedVisibleElementBindings) { >+ computeVisibleElementBindings(); >+ } >+ return this.visibleFields; >+ } >+ >+ public ObjectVector getVisibleMethods() { >+ if (!this.hasComputedVisibleElementBindings) { >+ computeVisibleElementBindings(); >+ } >+ return this.visibleMethods; >+ } > } >diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java >index e4e1e3c..d1eec1d 100644 >--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java >+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java >@@ -531,13 +531,13 @@ > } > } > >- if ((c1 = ScannerHelper.getNumericValue(source[pos++])) > 15 >+ if ((c1 = ScannerHelper.getHexadecimalValue(source[pos++])) > 15 > || c1 < 0 >- || (c2 = ScannerHelper.getNumericValue(source[pos++])) > 15 >+ || (c2 = ScannerHelper.getHexadecimalValue(source[pos++])) > 15 > || c2 < 0 >- || (c3 = ScannerHelper.getNumericValue(source[pos++])) > 15 >+ || (c3 = ScannerHelper.getHexadecimalValue(source[pos++])) > 15 > || c3 < 0 >- || (c4 = ScannerHelper.getNumericValue(source[pos++])) > 15 >+ || (c4 = ScannerHelper.getHexadecimalValue(source[pos++])) > 15 > || c4 < 0) { > return false; > } else { >diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java >index afd0ccc..fc89307 100644 >--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java >+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -1167,7 +1167,8 @@ > if (prevKind == K_BETWEEN_NEW_AND_LEFT_BRACKET) { > > AllocationExpression exp; >- if (this.expressionPtr > -1 && this.expressionStack[this.expressionPtr] instanceof AllocationExpression) { >+ if (this.expressionPtr > -1 && this.expressionStack[this.expressionPtr] instanceof AllocationExpression >+ && this.invocationType == QUALIFIED_ALLOCATION) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=361963 > exp = new QualifiedAllocationExpression(); > exp.type = ref; > ((QualifiedAllocationExpression)exp).enclosingInstance = this.expressionStack[this.expressionPtr]; >@@ -2627,6 +2628,9 @@ > arg.annotations = new Annotation[length], > 0, > length); >+ RecoveredType currentRecoveryType = this.currentRecoveryType(); >+ if (currentRecoveryType != null) >+ currentRecoveryType.annotationsConsumed(arg.annotations); > } > > arg.isCatchArgument = topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_BETWEEN_CATCH_AND_RIGHT_PAREN; >diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionScanner.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionScanner.java >index e63246b..e21f03f 100644 >--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionScanner.java >+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionScanner.java >@@ -552,13 +552,13 @@ > while (this.source[this.currentPosition] == 'u') { > this.currentPosition++; > } >- if ((c1 = ScannerHelper.getNumericValue(this.source[this.currentPosition++])) > 15 >+ if ((c1 = ScannerHelper.getHexadecimalValue(this.source[this.currentPosition++])) > 15 > || c1 < 0 >- || (c2 = ScannerHelper.getNumericValue(this.source[this.currentPosition++])) > 15 >+ || (c2 = ScannerHelper.getHexadecimalValue(this.source[this.currentPosition++])) > 15 > || c2 < 0 >- || (c3 = ScannerHelper.getNumericValue(this.source[this.currentPosition++])) > 15 >+ || (c3 = ScannerHelper.getHexadecimalValue(this.source[this.currentPosition++])) > 15 > || c3 < 0 >- || (c4 = ScannerHelper.getNumericValue(this.source[this.currentPosition++])) > 15 >+ || (c4 = ScannerHelper.getHexadecimalValue(this.source[this.currentPosition++])) > 15 > || c4 < 0) { > throw new InvalidInputException(INVALID_UNICODE_ESCAPE); > } else { >@@ -585,13 +585,13 @@ > while (this.source[this.currentPosition] == 'u') { > this.currentPosition++; > } >- if ((c1 = ScannerHelper.getNumericValue(this.source[this.currentPosition++])) > 15 >+ if ((c1 = ScannerHelper.getHexadecimalValue(this.source[this.currentPosition++])) > 15 > || c1 < 0 >- || (c2 = ScannerHelper.getNumericValue(this.source[this.currentPosition++])) > 15 >+ || (c2 = ScannerHelper.getHexadecimalValue(this.source[this.currentPosition++])) > 15 > || c2 < 0 >- || (c3 = ScannerHelper.getNumericValue(this.source[this.currentPosition++])) > 15 >+ || (c3 = ScannerHelper.getHexadecimalValue(this.source[this.currentPosition++])) > 15 > || c3 < 0 >- || (c4 = ScannerHelper.getNumericValue(this.source[this.currentPosition++])) > 15 >+ || (c4 = ScannerHelper.getHexadecimalValue(this.source[this.currentPosition++])) > 15 > || c4 < 0) { > throw new InvalidInputException(INVALID_UNICODE_ESCAPE); > } else { >@@ -623,13 +623,13 @@ > } > //-------------unicode traitement ------------ > int c1 = 0, c2 = 0, c3 = 0, c4 = 0; >- if ((c1 = ScannerHelper.getNumericValue(this.source[index++])) > 15 >+ if ((c1 = ScannerHelper.getHexadecimalValue(this.source[index++])) > 15 > || c1 < 0 >- || (c2 = ScannerHelper.getNumericValue(this.source[index++])) > 15 >+ || (c2 = ScannerHelper.getHexadecimalValue(this.source[index++])) > 15 > || c2 < 0 >- || (c3 = ScannerHelper.getNumericValue(this.source[index++])) > 15 >+ || (c3 = ScannerHelper.getHexadecimalValue(this.source[index++])) > 15 > || c3 < 0 >- || (c4 = ScannerHelper.getNumericValue(this.source[index++])) > 15 >+ || (c4 = ScannerHelper.getHexadecimalValue(this.source[index++])) > 15 > || c4 < 0) { > this.currentPosition = index; > throw new InvalidInputException(INVALID_UNICODE_ESCAPE); >diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java >index 5e59a1b..0be1b54 100644 >--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java >+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java >@@ -634,6 +634,9 @@ > arg.annotations = new Annotation[length], > 0, > length); >+ RecoveredType currentRecoveryType = this.currentRecoveryType(); >+ if (currentRecoveryType != null) >+ currentRecoveryType.annotationsConsumed(arg.annotations); > } > > pushOnAstStack(arg); >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java >index fa88bd9..c8844a3 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -116,7 +116,30 @@ > * Benjamin Muskalla - added the following constants > * MissingSynchronizedModifierInInheritedMethod > * Stephan Herrmann - added the following constants >- * UnusedObjectAllocation >+ * UnusedObjectAllocation >+ * PotentiallyUnclosedCloseable >+ * PotentiallyUnclosedCloseableAtExit >+ * UnclosedCloseable >+ * UnclosedCloseableAtExit >+ * ExplicitlyClosedAutoCloseable >+ * RequiredNonNullButProvidedNull >+ * RequiredNonNullButProvidedPotentialNull >+ * RequiredNonNullButProvidedUnknown >+ * NullAnnotationNameMustBeQualified >+ * IllegalReturnNullityRedefinition >+ * IllegalRedefinitionToNonNullParameter >+ * IllegalDefinitionToNonNullParameter >+ * ParameterLackingNonNullAnnotation >+ * ParameterLackingNullableAnnotation >+ * PotentialNullMessageSendReference >+ * RedundantNullCheckOnNonNullMessageSend >+ * CannotImplementIncompatibleNullness >+ * RedundantNullAnnotation >+ * RedundantNullDefaultAnnotation >+ * RedundantNullDefaultAnnotationPackage >+ * RedundantNullDefaultAnnotationType >+ * RedundantNullDefaultAnnotationMethod >+ * ContradictoryNullAnnotations > *******************************************************************************/ > package org.eclipse.jdt.core.compiler; > >@@ -1337,6 +1360,10 @@ > int SafeVarargsOnNonFinalInstanceMethod = MethodRelated + 805; > /** @since 3.7.1 */ > int PotentialHeapPollutionFromVararg = MethodRelated + 806; >+ /** @since 3.8 */ >+ int VarargsElementTypeNotVisible = MethodRelated + 807; >+ /** @since 3.8 */ >+ int VarargsElementTypeNotVisibleForConstructor = ConstructorRelated + 808; > /** > * Javadoc Generic > */ >@@ -1394,6 +1421,59 @@ > int DiamondNotBelow17 = TypeRelated + 883; > /** @since 3.7.1 */ > int RedundantSpecificationOfTypeArguments = TypeRelated + 884; >+ /** @since 3.8 */ >+ int PotentiallyUnclosedCloseable = Internal + 885; >+ /** @since 3.8 */ >+ int PotentiallyUnclosedCloseableAtExit = Internal + 886; >+ /** @since 3.8 */ >+ int UnclosedCloseable = Internal + 887; >+ /** @since 3.8 */ >+ int UnclosedCloseableAtExit = Internal + 888; >+ /** @since 3.8 */ >+ int ExplicitlyClosedAutoCloseable = Internal + 889; >+ /** @since 3.8 */ >+ int SwitchOnEnumNotBelow15 = TypeRelated + 890; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=360317 >+ /** >+ * Errors/warnings from annotation based null analysis >+ */ >+ /** @since 3.8 */ >+ int RequiredNonNullButProvidedNull = TypeRelated + 910; >+ /** @since 3.8 */ >+ int RequiredNonNullButProvidedPotentialNull = TypeRelated + 911; >+ /** @since 3.8 */ >+ int RequiredNonNullButProvidedUnknown = TypeRelated + 912; >+ // removed during 3.8 M6: ImportRelated + 913 >+ /** @since 3.8 */ >+ int IllegalReturnNullityRedefinition = MethodRelated + 914; >+ /** @since 3.8 */ >+ int IllegalRedefinitionToNonNullParameter = MethodRelated + 915; >+ /** @since 3.8 */ >+ int IllegalDefinitionToNonNullParameter = MethodRelated + 916; >+ /** @since 3.8 */ >+ int ParameterLackingNonNullAnnotation = MethodRelated + 917; >+ /** @since 3.8 */ >+ int ParameterLackingNullableAnnotation = MethodRelated + 918; >+ /** @since 3.8 */ >+ int PotentialNullMessageSendReference = Internal + 919; >+ /** @since 3.8 */ >+ int RedundantNullCheckOnNonNullMessageSend = Internal + 920; >+ /** @since 3.8 */ >+ int CannotImplementIncompatibleNullness = Internal + 921; >+ /** @since 3.8 */ >+ int RedundantNullAnnotation = MethodRelated + 922; >+ /** @since 3.8 */ >+ int IllegalAnnotationForBaseType = TypeRelated + 923; >+ /** @since 3.8 */ >+ int RedundantNullDefaultAnnotation = Internal + 925; >+ /** @since 3.8 */ >+ int RedundantNullDefaultAnnotationPackage = Internal + 926; >+ /** @since 3.8 */ >+ int RedundantNullDefaultAnnotationType = Internal + 927; >+ /** @since 3.8 */ >+ int RedundantNullDefaultAnnotationMethod = Internal + 928; >+ /** @since 3.8 */ >+ int ContradictoryNullAnnotations = Internal + 929; >+ > /** > * External problems -- These are problems defined by other plugins > */ >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/Compiler.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/Compiler.java >index 44a69a0..cbe6196 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/Compiler.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/Compiler.java >@@ -7,7 +7,9 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >- * Stephan Herrmann - contribution for bug 337868 - [compiler][model] incomplete support for package-info.java when using SearchableEnvironment >+ * Stephan Herrmann - contributions for >+ * bug 337868 - [compiler][model] incomplete support for package-info.java when using SearchableEnvironment >+ * bug 186342 - [compiler][null] Using annotations for null checking > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler; > >@@ -695,6 +697,7 @@ > > // Switch the current policy and compilation result for this unit to the requested one. > for (int i = 0; i < maxUnits; i++) { >+ CompilationResult unitResult = null; > try { > if (this.options.verbose) { > this.out.println( >@@ -707,8 +710,7 @@ > } > // diet parsing for large collection of units > CompilationUnitDeclaration parsedUnit; >- CompilationResult unitResult = >- new CompilationResult(sourceUnits[i], i, maxUnits, this.options.maxProblemsPerUnit); >+ unitResult = new CompilationResult(sourceUnits[i], i, maxUnits, this.options.maxProblemsPerUnit); > long parseStart = System.currentTimeMillis(); > if (this.totalUnits < this.parseThreshold) { > parsedUnit = this.parser.parse(sourceUnits[i], unitResult); >@@ -727,6 +729,11 @@ > } > //} catch (AbortCompilationUnit e) { > // requestor.acceptResult(unitResult.tagAsAccepted()); >+ } catch (AbortCompilation a) { >+ // best effort to find a way for reporting this problem: >+ if (a.compilationResult == null) >+ a.compilationResult = unitResult; >+ throw a; > } finally { > sourceUnits[i] = null; // no longer hold onto the unit > } >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java >index 892538a..5aae1c7 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -9,7 +9,10 @@ > * IBM Corporation - initial API and implementation > * Matt McCutchen - partial fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=122995 > * Karen Moore - fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=207411 >- * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 185682 - Increment/decrement operators mark local variables as read >+ * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for >+ * bug 185682 - Increment/decrement operators mark local variables as read >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 365519 - editorial cleanup after bug 186342 and bug 365387 > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >@@ -253,6 +256,9 @@ > > // this is only used for method invocation as the expression inside an expression statement > public static final int InsideExpressionStatement = Bit5; >+ >+ // for annotation reference, signal if annotation was created from a default: >+ public static final int IsSynthetic = ASTNode.Bit7; > > public ASTNode() { > >@@ -601,7 +607,7 @@ > local.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved); > if (length > 0) { > annotations = new AnnotationBinding[length]; >- local.setAnnotations(annotations); >+ local.setAnnotations(annotations, scope); > } > break; > default : >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java >index 228e6e8..d4f065e 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,13 +7,17 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contributions for >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 367203 - [compiler][null] detect assigning null to nonnull argument >+ * bug 365519 - editorial cleanup after bug 186342 and bug 365387 >+ * bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > > import org.eclipse.jdt.core.compiler.*; > import org.eclipse.jdt.internal.compiler.*; > import org.eclipse.jdt.internal.compiler.flow.FlowInfo; >-import org.eclipse.jdt.internal.compiler.flow.InitializationFlowContext; > import org.eclipse.jdt.internal.compiler.impl.*; > import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; > import org.eclipse.jdt.internal.compiler.codegen.*; >@@ -69,7 +73,24 @@ > } > } > >- public abstract void analyseCode(ClassScope classScope, InitializationFlowContext initializationContext, FlowInfo info); >+ /** >+ * When a method is accessed via SourceTypeBinding.resolveTypesFor(MethodBinding) >+ * we create the argument binding and resolve annotations in order to compute null annotation tagbits. >+ */ >+ public void createArgumentBindings() { >+ if (this.arguments != null && this.binding != null) { >+ for (int i = 0, length = this.arguments.length; i < length; i++) { >+ Argument argument = this.arguments[i]; >+ argument.createBinding(this.scope, this.binding.parameters[i]); >+ // createBinding() has resolved annotations, now transfer nullness info from the argument to the method: >+ if ((argument.binding.tagBits & (TagBits.AnnotationNonNull|TagBits.AnnotationNullable)) != 0) { >+ if (this.binding.parameterNonNullness == null) >+ this.binding.parameterNonNullness = new Boolean[this.arguments.length]; >+ this.binding.parameterNonNullness[i] = Boolean.valueOf((argument.binding.tagBits & TagBits.AnnotationNonNull) != 0); >+ } >+ } >+ } >+ } > > /** > * Bind and add argument's binding into the scope of the method >@@ -147,6 +168,28 @@ > } > } > >+ /** >+ * Feed null information from argument annotations into the analysis and mark arguments as assigned. >+ */ >+ void analyseArguments(FlowInfo flowInfo) { >+ if (this.arguments != null) { >+ for (int i = 0, count = this.arguments.length; i < count; i++) { >+ if (this.binding.parameterNonNullness != null) { >+ // leverage null-info from parameter annotations: >+ Boolean nonNullNess = this.binding.parameterNonNullness[i]; >+ if (nonNullNess != null) { >+ if (nonNullNess.booleanValue()) >+ flowInfo.markAsDefinitelyNonNull(this.arguments[i].binding); >+ else >+ flowInfo.markPotentiallyNullBit(this.arguments[i].binding); >+ } >+ } >+ // tag parameters as being set: >+ flowInfo.markAsDefinitelyAssigned(this.arguments[i].binding); >+ } >+ } >+ } >+ > public CompilationResult compilationResult() { > > return this.compilationResult; >@@ -185,17 +228,10 @@ > // a fatal error was detected during code generation, need to restart code gen if possible > if (e.compilationResult == CodeStream.RESTART_IN_WIDE_MODE) { > // a branch target required a goto_w, restart code gen in wide mode. >- if (!restart) { >- classFile.contentsOffset = problemResetPC; >- classFile.methodCount--; >- classFile.codeStream.resetInWideMode(); // request wide mode >- restart = true; >- } else { >- // after restarting in wide mode, code generation failed again >- // report a problem >- restart = false; >- abort = true; >- } >+ classFile.contentsOffset = problemResetPC; >+ classFile.methodCount--; >+ classFile.codeStream.resetInWideMode(); // request wide mode >+ restart = true; > } else if (e.compilationResult == CodeStream.RESTART_CODE_GEN_FOR_UNUSED_LOCALS_MODE) { > classFile.contentsOffset = problemResetPC; > classFile.methodCount--; >@@ -282,6 +318,13 @@ > this.scope.problemReporter().noMoreAvailableSpaceForArgument(this.scope.locals[i], this.scope.locals[i].declaration); > } > } >+ } >+ >+ public CompilationUnitDeclaration getCompilationUnitDeclaration() { >+ if (this.scope != null) { >+ return this.scope.compilationUnitScope().referenceContext; >+ } >+ return null; > } > > public boolean hasErrors() { >@@ -419,6 +462,7 @@ > bindThrownExceptions(); > resolveJavadoc(); > resolveAnnotations(this.scope, this.annotations, this.binding); >+ validateNullAnnotations(); > resolveStatements(); > // check @Deprecated annotation presence > if (this.binding != null >@@ -482,4 +526,18 @@ > public TypeParameter[] typeParameters() { > return null; > } >+ >+ void validateNullAnnotations() { >+ // null annotations on parameters? >+ if (this.binding != null && this.binding.parameterNonNullness != null) { >+ int length = this.binding.parameters.length; >+ for (int i=0; i<length; i++) { >+ if (this.binding.parameterNonNullness[i] != null) { >+ long nullAnnotationTagBit = this.binding.parameterNonNullness[i].booleanValue() >+ ? TagBits.AnnotationNonNull : TagBits.AnnotationNullable; >+ this.scope.validateNullAnnotation(nullAnnotationTagBit, this.arguments[i].type, this.arguments[i].annotations); >+ } >+ } >+ } >+ } > } >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java >index 2519ee4..ed98d20 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,9 +7,14 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >- * Stephan Herrmann - Contributions for >+ * Stephan Herrmann - Contributions for > * bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used > * bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE >+ * bug 349326 - [1.7] new warning for missing try-with-resources >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 358903 - Filter practically unimportant resource leak warnings >+ * bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK >+ * bug 370639 - [compiler][resource] restore the default for resource leak warnings > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >@@ -35,22 +40,34 @@ > protected TypeBinding typeExpected; // for <> inference > public boolean inferredReturnType; > >+ public FakedTrackingVariable closeTracker; // when allocation a Closeable store a pre-liminary tracking variable here >+ > public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { > // check captured variables are initialized in current context (26134) > checkCapturedLocalInitializationIfNecessary((ReferenceBinding)this.binding.declaringClass.erasure(), currentScope, flowInfo); > > // process arguments > if (this.arguments != null) { >+ boolean analyseResources = currentScope.compilerOptions().analyseResourceLeaks; >+ boolean hasResourceWrapperType = analyseResources >+ && this.resolvedType instanceof ReferenceBinding >+ && ((ReferenceBinding)this.resolvedType).hasTypeBit(TypeIds.BitWrapperCloseable); > for (int i = 0, count = this.arguments.length; i < count; i++) { > flowInfo = > this.arguments[i] > .analyseCode(currentScope, flowContext, flowInfo) > .unconditionalInits(); >+ // if argument is an AutoCloseable insert info that it *may* be closed (by the target method, i.e.) >+ if (analyseResources && !hasResourceWrapperType) { // allocation of wrapped closeables is analyzed specially >+ flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.arguments[i], flowInfo, false); >+ } > if ((this.arguments[i].implicitConversion & TypeIds.UNBOXING) != 0) { > this.arguments[i].checkNPE(currentScope, flowContext, flowInfo); > } > } >+ analyseArguments(currentScope, flowContext, flowInfo, this.binding, this.arguments); > } >+ > // record some dependency information for exception types > ReferenceBinding[] thrownExceptions; > if (((thrownExceptions = this.binding.thrownExceptions).length) != 0) { >@@ -65,6 +82,11 @@ > flowInfo.unconditionalCopy(), > currentScope); > } >+ >+ // after having analysed exceptions above start tracking newly allocated resource: >+ if (FakedTrackingVariable.isAnyCloseable(this.resolvedType) && currentScope.compilerOptions().analyseResourceLeaks) >+ FakedTrackingVariable.analyseCloseableAllocation(currentScope, flowInfo, this); >+ > if (this.binding.declaringClass.isMemberType() && !this.binding.declaringClass.isStatic()) { > // allocating a non-static member type without an enclosing instance of parent type > // https://bugs.eclipse.org/bugs/show_bug.cgi?id=335845 >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java >index d19c24c..1331b11 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,6 +7,9 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contributions for >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 365662 - [compiler][null] warn on contradictory and redundant null annotations > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >@@ -24,6 +27,8 @@ > public abstract class Annotation extends Expression { > > final static MemberValuePair[] NoValuePairs = new MemberValuePair[0]; >+ private static final long TAGBITS_NULLABLE_OR_NONNULL = TagBits.AnnotationNullable|TagBits.AnnotationNonNull; >+ > public int declarationSourceEnd; > public Binding recipient; > >@@ -167,11 +172,21 @@ > case TypeIds.T_JavaLangInvokeMethodHandlePolymorphicSignature : > tagBits |= TagBits.AnnotationPolymorphicSignature; > break; >- case TypeIds.T_JavaxAnnotationPostConstruct : >- tagBits |= TagBits.AnnotationPostConstruct; >+ case TypeIds.T_ConfiguredAnnotationNullable : >+ tagBits |= TagBits.AnnotationNullable; > break; >- case TypeIds.T_JavaxAnnotationPreDestroy : >- tagBits |= TagBits.AnnotationPreDestroy; >+ case TypeIds.T_ConfiguredAnnotationNonNull : >+ tagBits |= TagBits.AnnotationNonNull; >+ break; >+ case TypeIds.T_ConfiguredAnnotationNonNullByDefault : >+ if (valueAttribute != null >+ && valueAttribute.value instanceof FalseLiteral) >+ { >+ // parameter 'false' means: this annotation cancels any defaults >+ tagBits |= TagBits.AnnotationNullUnspecifiedByDefault; >+ break; >+ } >+ tagBits |= TagBits.AnnotationNonNullByDefault; > break; > } > return tagBits; >@@ -376,6 +391,10 @@ > AbstractMethodDeclaration methodDeclaration = sourceType.scope.referenceContext.declarationOf(sourceMethod); > recordSuppressWarnings(scope, methodDeclaration.declarationSourceStart, methodDeclaration.declarationSourceEnd, scope.compilerOptions().suppressWarnings); > } >+ if ((sourceMethod.tagBits & TAGBITS_NULLABLE_OR_NONNULL) == TAGBITS_NULLABLE_OR_NONNULL) { >+ scope.problemReporter().contradictoryNullAnnotations(this); >+ sourceMethod.tagBits &= ~TAGBITS_NULLABLE_OR_NONNULL; // avoid secondary problems >+ } > break; > case Binding.FIELD : > FieldBinding sourceField = (FieldBinding) this.recipient; >@@ -393,6 +412,10 @@ > LocalDeclaration localDeclaration = variable.declaration; > recordSuppressWarnings(scope, localDeclaration.declarationSourceStart, localDeclaration.declarationSourceEnd, scope.compilerOptions().suppressWarnings); > } >+ if ((variable.tagBits & TAGBITS_NULLABLE_OR_NONNULL) == TAGBITS_NULLABLE_OR_NONNULL) { >+ scope.problemReporter().contradictoryNullAnnotations(this); >+ variable.tagBits &= ~TAGBITS_NULLABLE_OR_NONNULL; // avoid secondary problems >+ } > break; > } > } >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java >index acad2e6..9c4eb4b 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java >@@ -4,9 +4,12 @@ > * 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: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contributions for >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 365519 - editorial cleanup after bug 186342 and bug 365387 > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >@@ -30,7 +33,25 @@ > this.bits |= (IsLocalDeclarationReachable | IsArgument); > } > >+ public void createBinding(MethodScope scope, TypeBinding typeBinding) { >+ if (this.binding == null) { >+ // for default constructors and fake implementation of abstract methods >+ this.binding = new LocalVariableBinding(this, typeBinding, this.modifiers, true /*isArgument*/); >+ } else if (!this.binding.type.isValidBinding()) { >+ AbstractMethodDeclaration methodDecl = scope.referenceMethod(); >+ if (methodDecl != null) { >+ MethodBinding methodBinding = methodDecl.binding; >+ if (methodBinding != null) { >+ methodBinding.tagBits |= TagBits.HasUnresolvedArguments; >+ } >+ } >+ } >+ resolveAnnotations(scope, this.annotations, this.binding); >+ this.binding.declaration = this; >+ } >+ > public void bind(MethodScope scope, TypeBinding typeBinding, boolean used) { >+ createBinding(scope, typeBinding); // basically a no-op if createBinding() was called before > > // record the resolved type into the type reference > Binding existingVariable = scope.getBinding(this.name, Binding.VARIABLE, this, false /*do not resolve hidden field*/); >@@ -52,22 +73,7 @@ > scope.problemReporter().localVariableHiding(this, existingVariable, isSpecialArgument); > } > } >- >- if (this.binding == null) { >- this.binding = new LocalVariableBinding(this, typeBinding, this.modifiers, true); >- } else if (!this.binding.type.isValidBinding()) { >- AbstractMethodDeclaration methodDecl = scope.referenceMethod(); >- if (methodDecl != null) { >- MethodBinding methodBinding = methodDecl.binding; >- if (methodBinding != null) { >- methodBinding.tagBits |= TagBits.HasUnresolvedArguments; >- } >- } >- } > scope.addLocalVariable(this.binding); >- resolveAnnotations(scope, this.annotations, this.binding); >- //true stand for argument instead of just local >- this.binding.declaration = this; > this.binding.useFlag = used ? LocalVariableBinding.USED : LocalVariableBinding.UNUSED; > } > >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayInitializer.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayInitializer.java >index afe4153..41027f8 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayInitializer.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayInitializer.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,6 +7,9 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contributions for >+ * bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK >+ * bug 370639 - [compiler][resource] restore the default for resource leak warnings > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >@@ -32,8 +35,13 @@ > public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { > > if (this.expressions != null) { >+ boolean analyseResources = currentScope.compilerOptions().analyseResourceLeaks; > for (int i = 0, max = this.expressions.length; i < max; i++) { > flowInfo = this.expressions[i].analyseCode(currentScope, flowContext, flowInfo).unconditionalInits(); >+ >+ if (analyseResources && FakedTrackingVariable.isAnyCloseable(this.expressions[i].resolvedType)) { >+ flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.expressions[i], flowInfo, false); >+ } > } > } > return flowInfo; >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayReference.java >index ebad17f..9b12104 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayReference.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayReference.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2008 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java >index 5404643..3d4eda6 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java >@@ -1,17 +1,21 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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: > * IBM Corporation - initial API and implementation > * Genady Beriozkin - added support for reporting assignment with no effect >- * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for >+ * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for > * bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE > * bug 292478 - Report potentially null across variable assignment > * bug 335093 - [compiler][null] minimal hook for future null annotation support >+ * bug 349326 - [1.7] new warning for missing try-with-resources >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 358903 - Filter practically unimportant resource leak warnings >+ * bug 370639 - [compiler][resource] restore the default for resource leak warnings > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >@@ -44,9 +48,28 @@ > if ((this.expression.implicitConversion & TypeIds.UNBOXING) != 0) { > this.expression.checkNPE(currentScope, flowContext, flowInfo); > } >+ >+ FlowInfo preInitInfo = null; >+ boolean shouldAnalyseResource = local != null >+ && flowInfo.reachMode() == FlowInfo.REACHABLE >+ && currentScope.compilerOptions().analyseResourceLeaks >+ && (FakedTrackingVariable.isAnyCloseable(this.expression.resolvedType) >+ || this.expression.resolvedType == TypeBinding.NULL); >+ if (shouldAnalyseResource) { >+ preInitInfo = flowInfo.unconditionalCopy(); >+ // analysis of resource leaks needs additional context while analyzing the RHS: >+ FakedTrackingVariable.preConnectTrackerAcrossAssignment(this, local, this.expression); >+ } >+ > flowInfo = ((Reference) this.lhs) > .analyseAssignment(currentScope, flowContext, flowInfo, this, false) > .unconditionalInits(); >+ >+ if (shouldAnalyseResource) >+ FakedTrackingVariable.handleResourceAssignment(currentScope, preInitInfo, flowInfo, this, this.expression, local); >+ else >+ FakedTrackingVariable.cleanUpAfterAssignment(currentScope, this.lhs.bits, this.expression); >+ > int nullStatus = this.expression.nullStatus(flowInfo); > if (local != null && (local.type.tagBits & TagBits.IsBaseType) == 0) { > if (nullStatus == FlowInfo.NULL) { >@@ -54,7 +77,7 @@ > FlowContext.CAN_ONLY_NULL | FlowContext.IN_ASSIGNMENT, flowInfo); > } > } >- nullStatus = checkAgainstNullAnnotation(currentScope, local, nullStatus); >+ nullStatus = checkAssignmentAgainstNullAnnotation(currentScope, flowContext, local, nullStatus, this.expression); > if (local != null && (local.type.tagBits & TagBits.IsBaseType) == 0) { > flowInfo.markNullStatus(local, nullStatus); > if (flowContext.initsOnFinally != null) >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Block.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Block.java >index cb789a4..26606d4 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Block.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Block.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,6 +7,9 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contributions for >+ * bug 349326 - [1.7] new warning for missing try-with-resources >+ * bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >@@ -32,10 +35,12 @@ > int complaintLevel = (flowInfo.reachMode() & FlowInfo.UNREACHABLE) != 0 ? Statement.COMPLAINED_FAKE_REACHABLE : Statement.NOT_COMPLAINED; > for (int i = 0, max = this.statements.length; i < max; i++) { > Statement stat = this.statements[i]; >- if ((complaintLevel = stat.complainIfUnreachable(flowInfo, this.scope, complaintLevel)) < Statement.COMPLAINED_UNREACHABLE) { >+ if ((complaintLevel = stat.complainIfUnreachable(flowInfo, this.scope, complaintLevel, true)) < Statement.COMPLAINED_UNREACHABLE) { > flowInfo = stat.analyseCode(this.scope, flowContext, flowInfo); > } > } >+ if (this.explicitDeclarations > 0) // if block has its own scope analyze tracking vars now: >+ this.scope.checkUnclosedCloseables(flowInfo, flowContext, null, null); > return flowInfo; > } > /** >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java >index 3c59918..cc390d3 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -72,7 +72,7 @@ > targetContext.recordBreakFrom(flowInfo); > break; > } >- } while ((traversedContext = traversedContext.parent) != null); >+ } while ((traversedContext = traversedContext.getLocalParent()) != null); > > // resize subroutines > if (subCount != this.subroutines.length) { >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java >index 3ccb0ba..2dd5580 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -118,16 +118,11 @@ > // cases. > if (e.compilationResult == CodeStream.RESTART_IN_WIDE_MODE) { > // a branch target required a goto_w, restart code gen in wide mode. >- if (!restart) { >- classFile.contentsOffset = clinitOffset; >- classFile.methodCount--; >- classFile.codeStream.resetInWideMode(); // request wide mode >- // restart method generation >- restart = true; >- } else { >- classFile.contentsOffset = clinitOffset; >- classFile.methodCount--; >- } >+ classFile.contentsOffset = clinitOffset; >+ classFile.methodCount--; >+ classFile.codeStream.resetInWideMode(); // request wide mode >+ // restart method generation >+ restart = true; > } else if (e.compilationResult == CodeStream.RESTART_CODE_GEN_FOR_UNUSED_LOCALS_MODE) { > classFile.contentsOffset = clinitOffset; > classFile.methodCount--; >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java >index eb6f64a..754305e 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -364,6 +364,10 @@ > } > } > >+public CompilationUnitDeclaration getCompilationUnitDeclaration() { >+ return this; >+} >+ > public char[] getFileName() { > return this.compilationResult.getFileName(); > } >@@ -394,6 +398,24 @@ > return CharOperation.equals(getMainTypeName(), TypeConstants.PACKAGE_INFO_NAME); > } > >+public boolean isSuppressed(CategorizedProblem problem) { >+ if (this.suppressWarningsCount == 0) return false; >+ int irritant = ProblemReporter.getIrritant(problem.getID()); >+ if (irritant == 0) return false; >+ int start = problem.getSourceStart(); >+ int end = problem.getSourceEnd(); >+ nextSuppress: for (int iSuppress = 0, suppressCount = this.suppressWarningsCount; iSuppress < suppressCount; iSuppress++) { >+ long position = this.suppressWarningScopePositions[iSuppress]; >+ int startSuppress = (int) (position >>> 32); >+ int endSuppress = (int) position; >+ if (start < startSuppress) continue nextSuppress; >+ if (end > endSuppress) continue nextSuppress; >+ if (this.suppressWarningIrritants[iSuppress].isSet(irritant)) >+ return true; >+ } >+ return false; >+} >+ > public boolean hasErrors() { > return this.ignoreFurtherInvestigation; > } >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java >index f5d9416..5907c61 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java >@@ -12,6 +12,7 @@ > * bug 292478 - Report potentially null across variable assignment > * bug 324178 - [null] ConditionalExpression.nullStatus(..) doesn't take into account the analysis of condition itself > * bug 354554 - [null] conditional with redundant condition yields weak error message >+ * bug 349326 - [1.7] new warning for missing try-with-resources > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >@@ -65,7 +66,7 @@ > trueFlowInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD); > } > if (!isKnowDeadCodePattern(this.condition) || currentScope.compilerOptions().reportDeadCodeInTrivialIfStatement) { >- this.valueIfTrue.complainIfUnreachable(trueFlowInfo, currentScope, initialComplaintLevel); >+ this.valueIfTrue.complainIfUnreachable(trueFlowInfo, currentScope, initialComplaintLevel, false); > } > } > this.trueInitStateIndex = currentScope.methodScope().recordInitializationStates(trueFlowInfo); >@@ -78,7 +79,7 @@ > falseFlowInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD); > } > if (!isKnowDeadCodePattern(this.condition) || currentScope.compilerOptions().reportDeadCodeInTrivialIfStatement) { >- this.valueIfFalse.complainIfUnreachable(falseFlowInfo, currentScope, initialComplaintLevel); >+ this.valueIfFalse.complainIfUnreachable(falseFlowInfo, currentScope, initialComplaintLevel, true); > } > } > this.falseInitStateIndex = currentScope.methodScope().recordInitializationStates(falseFlowInfo); >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java >index e7c790a..1b955e0 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,7 +7,12 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >- * Stephan Herrmann - Contribution for Bug 343713 - [compiler] bogus line number in constructor of inner class in 1.5 compliance >+ * Stephan Herrmann - Contributions for >+ * bug 343713 - [compiler] bogus line number in constructor of inner class in 1.5 compliance >+ * bug 349326 - [1.7] new warning for missing try-with-resources >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 361407 - Resource leak warning when resource is assigned to a field outside of constructor >+ * bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >@@ -32,18 +37,9 @@ > public ConstructorDeclaration(CompilationResult compilationResult){ > super(compilationResult); > } >- >-/** >- * @see org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration#analyseCode(org.eclipse.jdt.internal.compiler.lookup.ClassScope, org.eclipse.jdt.internal.compiler.flow.InitializationFlowContext, org.eclipse.jdt.internal.compiler.flow.FlowInfo) >- * @deprecated use instead {@link #analyseCode(ClassScope, InitializationFlowContext, FlowInfo, int)} >- */ >-public void analyseCode(ClassScope classScope, InitializationFlowContext initializerFlowContext, FlowInfo flowInfo) { >- analyseCode(classScope, initializerFlowContext, flowInfo, FlowInfo.REACHABLE); >-} >- > /** > * The flowInfo corresponds to non-static field initialization infos. It may be unreachable (155423), but still the explicit constructor call must be >- * analysed as reachable, since it will be generated in the end. >+ * analyzed as reachable, since it will be generated in the end. > */ > public void analyseCode(ClassScope classScope, InitializationFlowContext initializerFlowContext, FlowInfo flowInfo, int initialReachMode) { > if (this.ignoreFurtherInvestigation) >@@ -120,12 +116,8 @@ > } > } > >- // tag parameters as being set >- if (this.arguments != null) { >- for (int i = 0, count = this.arguments.length; i < count; i++) { >- flowInfo.markAsDefinitelyAssigned(this.arguments[i].binding); >- } >- } >+ // nullity and mark as assigned >+ analyseArguments(flowInfo); > > // propagate to constructor call > if (this.constructorCall != null) { >@@ -151,7 +143,7 @@ > int complaintLevel = (nonStaticFieldInfoReachMode & FlowInfo.UNREACHABLE) == 0 ? Statement.NOT_COMPLAINED : Statement.COMPLAINED_FAKE_REACHABLE; > for (int i = 0, count = this.statements.length; i < count; i++) { > Statement stat = this.statements[i]; >- if ((complaintLevel = stat.complainIfUnreachable(flowInfo, this.scope, complaintLevel)) < Statement.COMPLAINED_UNREACHABLE) { >+ if ((complaintLevel = stat.complainIfUnreachable(flowInfo, this.scope, complaintLevel, true)) < Statement.COMPLAINED_UNREACHABLE) { > flowInfo = stat.analyseCode(this.scope, constructorContext, flowInfo); > } > } >@@ -186,6 +178,7 @@ > constructorContext.complainIfUnusedExceptionHandlers(this); > // check unused parameters > this.scope.checkUnusedParameters(this.binding); >+ this.scope.checkUnclosedCloseables(flowInfo, null, null/*don't report against a specific location*/, null); > } catch (AbortMethod e) { > this.ignoreFurtherInvestigation = true; > } >@@ -220,15 +213,10 @@ > } catch (AbortMethod e) { > if (e.compilationResult == CodeStream.RESTART_IN_WIDE_MODE) { > // a branch target required a goto_w, restart code gen in wide mode. >- if (!restart) { >- classFile.contentsOffset = problemResetPC; >- classFile.methodCount--; >- classFile.codeStream.resetInWideMode(); // request wide mode >- restart = true; >- } else { >- restart = false; >- abort = true; >- } >+ classFile.contentsOffset = problemResetPC; >+ classFile.methodCount--; >+ classFile.codeStream.resetInWideMode(); // request wide mode >+ restart = true; > } else if (e.compilationResult == CodeStream.RESTART_CODE_GEN_FOR_UNUSED_LOCALS_MODE) { > classFile.contentsOffset = problemResetPC; > classFile.methodCount--; >@@ -416,6 +404,7 @@ > > ConstructorDeclaration targetConstructor = > ((ConstructorDeclaration)this.scope.referenceType().declarationOf(this.constructorCall.binding.original())); >+ if (targetConstructor == null) return false; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=358762 > if (this == targetConstructor) return true; // direct case > > if (visited == null) { // lazy allocation >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ContinueStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ContinueStatement.java >index 1641bc5..475fef2 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ContinueStatement.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ContinueStatement.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -75,7 +75,7 @@ > targetContext.recordContinueFrom(flowContext, flowInfo); > break; > } >- } while ((traversedContext = traversedContext.parent) != null); >+ } while ((traversedContext = traversedContext.getLocalParent()) != null); > > // resize subroutines > if (subCount != this.subroutines.length) { >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoStatement.java >index 5806ce8..774c7aa 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoStatement.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoStatement.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -101,7 +101,11 @@ > (this.action == null > ? actionInfo > : (actionInfo.mergedWith(loopingContext.initsOnContinue))).copy()); >- this.preConditionInitStateIndex = currentScope.methodScope().recordInitializationStates(actionInfo); >+ /* https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023, we reach the condition at the bottom via two arcs, >+ one by free fall and another by continuing... Merge initializations propagated through the two pathways, >+ cf, while and for loops. >+ */ >+ this.preConditionInitStateIndex = currentScope.methodScope().recordInitializationStates(actionInfo.mergedWith(loopingContext.initsOnContinue)); > if (!isConditionOptimizedFalse && this.continueLabel != null) { > loopingContext.complainOnDeferredFinalChecks(currentScope, condInfo); > condLoopContext.complainOnDeferredFinalChecks(currentScope, condInfo); >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EmptyStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EmptyStatement.java >index d6cbd10..904e564 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EmptyStatement.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EmptyStatement.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >@@ -29,12 +30,12 @@ > } > > // Report an error if necessary >- public int complainIfUnreachable(FlowInfo flowInfo, BlockScope scope, int complaintLevel) { >+ public int complainIfUnreachable(FlowInfo flowInfo, BlockScope scope, int complaintLevel, boolean endOfBlock) { > // before 1.4, empty statements are tolerated anywhere > if (scope.compilerOptions().complianceLevel < ClassFileConstants.JDK1_4) { > return complaintLevel; > } >- return super.complainIfUnreachable(flowInfo, scope, complaintLevel); >+ return super.complainIfUnreachable(flowInfo, scope, complaintLevel, endOfBlock); > } > > public void generateCode(BlockScope currentScope, CodeStream codeStream){ >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java >index a9ce3fc..9763111 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contribution for bug 186342 - [compiler][null] Using annotations for null checking > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >@@ -23,14 +24,28 @@ > super(left,right,operator); > } > private void checkNullComparison(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo, FlowInfo initsWhenTrue, FlowInfo initsWhenFalse) { >+ int rightStatus = this.right.nullStatus(flowInfo); >+ int leftStatus = this.left.nullStatus(flowInfo); >+ // check if either is a method annotated @NonNull and compared to null: >+ if (leftStatus == FlowInfo.NON_NULL && rightStatus == FlowInfo.NULL) { >+ if (this.left instanceof MessageSend) { >+ scope.problemReporter().messageSendRedundantCheckOnNonNull(((MessageSend) this.left).binding, this.left); >+ } >+ // TODO: handle all kinds of expressions (cf. also https://bugs.eclipse.org/364326) >+ } else if (leftStatus == FlowInfo.NULL && rightStatus == FlowInfo.NON_NULL) { >+ if (this.right instanceof MessageSend) { >+ scope.problemReporter().messageSendRedundantCheckOnNonNull(((MessageSend) this.right).binding, this.right); >+ } >+ // TODO: handle all kinds of expressions (cf. also https://bugs.eclipse.org/364326) >+ } > > LocalVariableBinding local = this.left.localVariableBinding(); > if (local != null && (local.type.tagBits & TagBits.IsBaseType) == 0) { >- checkVariableComparison(scope, flowContext, flowInfo, initsWhenTrue, initsWhenFalse, local, this.right.nullStatus(flowInfo), this.left); >+ checkVariableComparison(scope, flowContext, flowInfo, initsWhenTrue, initsWhenFalse, local, rightStatus, this.left); > } > local = this.right.localVariableBinding(); > if (local != null && (local.type.tagBits & TagBits.IsBaseType) == 0) { >- checkVariableComparison(scope, flowContext, flowInfo, initsWhenTrue, initsWhenFalse, local, this.left.nullStatus(flowInfo), this.right); >+ checkVariableComparison(scope, flowContext, flowInfo, initsWhenTrue, initsWhenFalse, local, leftStatus, this.right); > } > } > private void checkVariableComparison(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo, FlowInfo initsWhenTrue, FlowInfo initsWhenFalse, LocalVariableBinding local, int nullStatus, Expression reference) { >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java >index ba2219f..f081f32 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,7 +7,11 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >- * Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE >+ * Stephan Herrmann - Contributions for >+ * bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 361407 - Resource leak warning when resource is assigned to a field outside of constructor >+ * bug 370639 - [compiler][resource] restore the default for resource leak warnings > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >@@ -72,15 +76,21 @@ > } > // process arguments > if (this.arguments != null) { >+ boolean analyseResources = currentScope.compilerOptions().analyseResourceLeaks; > for (int i = 0, max = this.arguments.length; i < max; i++) { > flowInfo = > this.arguments[i] > .analyseCode(currentScope, flowContext, flowInfo) > .unconditionalInits(); >+ if (analyseResources) { >+ // if argument is an AutoCloseable insert info that it *may* be closed (by the target constructor, i.e.) >+ flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.arguments[i], flowInfo, false); >+ } > if ((this.arguments[i].implicitConversion & TypeIds.UNBOXING) != 0) { > this.arguments[i].checkNPE(currentScope, flowContext, flowInfo); > } > } >+ analyseArguments(currentScope, flowContext, flowInfo, this.binding, this.arguments); > } > > ReferenceBinding[] thrownExceptions; >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java >new file mode 100644 >index 0000000..4ac6c2f >--- /dev/null >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java >@@ -0,0 +1,791 @@ >+/******************************************************************************* >+ * Copyright (c) 2011, 2012 GK Software AG 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: >+ * Stephan Herrmann - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.internal.compiler.ast; >+ >+import java.util.HashMap; >+import java.util.Iterator; >+import java.util.Map; >+import java.util.Map.Entry; >+import java.util.Set; >+ >+import org.eclipse.jdt.internal.compiler.codegen.CodeStream; >+import org.eclipse.jdt.internal.compiler.flow.FlowContext; >+import org.eclipse.jdt.internal.compiler.flow.FlowInfo; >+import org.eclipse.jdt.internal.compiler.impl.Constant; >+import org.eclipse.jdt.internal.compiler.lookup.Binding; >+import org.eclipse.jdt.internal.compiler.lookup.BlockScope; >+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding; >+import org.eclipse.jdt.internal.compiler.lookup.MethodScope; >+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; >+import org.eclipse.jdt.internal.compiler.lookup.Scope; >+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; >+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; >+import org.eclipse.jdt.internal.compiler.lookup.TypeIds; >+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter; >+ >+/** >+ * A faked local variable declaration used for keeping track of data flows of a >+ * special variable. Certain events will be recorded by changing the null info >+ * for this variable. >+ * >+ * See bug 349326 - [1.7] new warning for missing try-with-resources >+ */ >+public class FakedTrackingVariable extends LocalDeclaration { >+ >+ // a call to close() was seen at least on one path: >+ private static final int CLOSE_SEEN = 1; >+ // the resource is shared with outside code either by >+ // - passing as an arg in a method call or >+ // - obtaining this from a method call or array reference >+ // Interpret that we may or may not be responsible for closing >+ private static final int SHARED_WITH_OUTSIDE = 2; >+ // the resource is likely owned by outside code (owner has responsibility to close): >+ // - obtained as argument of the current method, or via a field read >+ // - stored into a field >+ // - returned as the result of this method >+ private static final int OWNED_BY_OUTSIDE = 4; >+ // If close() is invoked from a nested method (inside a local type) report remaining problems only as potential: >+ private static final int CLOSED_IN_NESTED_METHOD = 8; >+ // explicit closing has been reported already against this resource: >+ private static final int REPORTED_EXPLICIT_CLOSE = 16; >+ // a location independent potential problem has been reported against this resource: >+ private static final int REPORTED_POTENTIAL_LEAK = 32; >+ // a location independent definitive problem has been reported against this resource: >+ private static final int REPORTED_DEFINITIVE_LEAK = 64; >+ >+ /** >+ * Bitset of {@link #CLOSE_SEEN}, {@link #SHARED_WITH_OUTSIDE}, {@link #OWNED_BY_OUTSIDE}, {@link #CLOSED_IN_NESTED_METHOD}, {@link #REPORTED_EXPLICIT_CLOSE}, {@link #REPORTED_POTENTIAL_LEAK} and {@link #REPORTED_DEFINITIVE_LEAK}. >+ */ >+ private int globalClosingState = 0; >+ >+ public LocalVariableBinding originalBinding; // the real local being tracked, can be null for preliminary track vars for allocation expressions >+ >+ public FakedTrackingVariable innerTracker; // chained tracking variable of a chained (wrapped) resource >+ public FakedTrackingVariable outerTracker; // inverse of 'innerTracker' >+ >+ MethodScope methodScope; // designates the method declaring this variable >+ >+ private HashMap recordedLocations; // initially null, ASTNode -> Integer >+ >+ // temporary storage while analyzing "res = new Res();": >+ private ASTNode currentAssignment; // temporarily store the assignment as the location for error reporting >+ >+ public FakedTrackingVariable(LocalVariableBinding original, ASTNode location) { >+ super(original.name, location.sourceStart, location.sourceEnd); >+ this.type = new SingleTypeReference( >+ TypeConstants.OBJECT, >+ ((long)this.sourceStart <<32)+this.sourceEnd); >+ this.methodScope = original.declaringScope.methodScope(); >+ this.originalBinding = original; >+ resolve(original.declaringScope); >+ } >+ >+ /* Create an unassigned tracking variable while analyzing an allocation expression: */ >+ private FakedTrackingVariable(BlockScope scope, ASTNode location) { >+ super("<unassigned Closeable value>".toCharArray(), location.sourceStart, location.sourceEnd); //$NON-NLS-1$ >+ this.type = new SingleTypeReference( >+ TypeConstants.OBJECT, >+ ((long)this.sourceStart <<32)+this.sourceEnd); >+ this.methodScope = scope.methodScope(); >+ this.originalBinding = null; >+ resolve(scope); >+ } >+ >+ public void generateCode(BlockScope currentScope, CodeStream codeStream) >+ { /* NOP - this variable is completely dummy, ie. for analysis only. */ } >+ >+ public void resolve (BlockScope scope) { >+ // only need the binding, which is used as reference in FlowInfo methods. >+ this.binding = new LocalVariableBinding( >+ this.name, >+ scope.getJavaLangObject(), // dummy, just needs to be a reference type >+ 0, >+ false); >+ this.binding.closeTracker = this; >+ this.binding.declaringScope = scope; >+ this.binding.setConstant(Constant.NotAConstant); >+ this.binding.useFlag = LocalVariableBinding.USED; >+ // use a free slot without assigning it: >+ this.binding.id = scope.registerTrackingVariable(this); >+ } >+ >+ /** >+ * If expression resolves to a value of type AutoCloseable answer the variable that tracks closing of that local. >+ * Covers two cases: >+ * <ul> >+ * <li>value is a local variable reference, create tracking variable it if needed. >+ * <li>value is an allocation expression, return a preliminary tracking variable if set. >+ * </ul> >+ * @param expression >+ * @return a new {@link FakedTrackingVariable} or null. >+ */ >+ public static FakedTrackingVariable getCloseTrackingVariable(Expression expression) { >+ while (true) { >+ if (expression instanceof CastExpression) >+ expression = ((CastExpression) expression).expression; >+ else if (expression instanceof Assignment) >+ expression = ((Assignment) expression).expression; >+ else >+ break; >+ } >+ if (expression instanceof SingleNameReference) { >+ SingleNameReference name = (SingleNameReference) expression; >+ if (name.binding instanceof LocalVariableBinding) { >+ LocalVariableBinding local = (LocalVariableBinding)name.binding; >+ if (local.closeTracker != null) >+ return local.closeTracker; >+ if (!isAnyCloseable(expression.resolvedType)) >+ return null; >+ // tracking var doesn't yet exist. This happens in finally block >+ // which is analyzed before the corresponding try block >+ Statement location = local.declaration; >+ local.closeTracker = new FakedTrackingVariable(local, location); >+ if (local.isParameter()) { >+ local.closeTracker.globalClosingState |= OWNED_BY_OUTSIDE; >+ // status of this tracker is now UNKNOWN >+ } >+ return local.closeTracker; >+ } >+ } else if (expression instanceof AllocationExpression) { >+ // return any preliminary tracking variable from analyseCloseableAllocation >+ return ((AllocationExpression) expression).closeTracker; >+ } >+ return null; >+ } >+ >+ /** >+ * Before analyzing an assignment of this shape: <code>singleName = new Allocation()</code> >+ * connect any tracking variable of the LHS with the allocation on the RHS. >+ * Also the assignment is temporarily stored in the tracking variable in case we need to >+ * report errors because the assignment leaves the old LHS value unclosed. >+ * In this case the assignment should be used as the error location. >+ * >+ * @param location the assignment/local declaration being analyzed >+ * @param local the local variable being assigned to >+ * @param rhs the rhs of the assignment resp. the initialization of the local variable declaration. >+ * <strong>Precondition:</strong> client has already checked that the resolved type of this expression is either a closeable type or NULL. >+ */ >+ public static void preConnectTrackerAcrossAssignment(ASTNode location, LocalVariableBinding local, Expression rhs) { >+ FakedTrackingVariable closeTracker = null; >+ if (rhs instanceof AllocationExpression) { >+ closeTracker = local.closeTracker; >+ if (closeTracker == null) { >+ if (rhs.resolvedType != TypeBinding.NULL) { // not NULL means valid closeable as per method precondition >+ closeTracker = new FakedTrackingVariable(local, location); >+ if (local.isParameter()) { >+ closeTracker.globalClosingState |= OWNED_BY_OUTSIDE; >+ } >+ } >+ } >+ if (closeTracker != null) { >+ closeTracker.currentAssignment = location; >+ AllocationExpression allocation = (AllocationExpression)rhs; >+ allocation.closeTracker = closeTracker; >+ if (allocation.arguments != null && allocation.arguments.length > 0) { >+ // also push into nested allocations, see https://bugs.eclipse.org/368709 >+ preConnectTrackerAcrossAssignment(location, local, allocation.arguments[0]); >+ } >+ } >+ } >+ } >+ >+ /** >+ * Compute/assign a tracking variable for a freshly allocated closeable value, using information from our white lists. >+ * See Bug 358903 - Filter practically unimportant resource leak warnings >+ */ >+ public static void analyseCloseableAllocation(BlockScope scope, FlowInfo flowInfo, AllocationExpression allocation) { >+ // client has checked that the resolvedType is an AutoCloseable, hence the following cast is safe: >+ if (((ReferenceBinding)allocation.resolvedType).hasTypeBit(TypeIds.BitResourceFreeCloseable)) { >+ // remove unnecessary attempts (closeable is not relevant) >+ if (allocation.closeTracker != null) { >+ scope.removeTrackingVar(allocation.closeTracker); >+ allocation.closeTracker = null; >+ } >+ } else if (((ReferenceBinding)allocation.resolvedType).hasTypeBit(TypeIds.BitWrapperCloseable)) { >+ boolean isWrapper = true; >+ if (allocation.arguments != null && allocation.arguments.length > 0) { >+ // find the wrapped resource represented by its tracking var: >+ FakedTrackingVariable innerTracker = findCloseTracker(scope, flowInfo, allocation.arguments[0]); >+ if (innerTracker != null) { >+ FakedTrackingVariable currentInner = innerTracker; >+ do { >+ if (currentInner == allocation.closeTracker) >+ return; // self wrap (res = new Res(res)) -> neither change (here) nor remove (below) >+ // also check for indirect cycles, see https://bugs.eclipse.org/368709 >+ currentInner = currentInner.innerTracker; >+ } while (currentInner != null); >+ int newStatus = FlowInfo.NULL; >+ if (allocation.closeTracker == null) { >+ allocation.closeTracker = new FakedTrackingVariable(scope, allocation); // no local available, closeable is unassigned >+ } else { >+ if (scope.finallyInfo != null) { >+ // inject results from analysing a finally block onto the newly connected wrapper >+ int finallyStatus = scope.finallyInfo.nullStatus(allocation.closeTracker.binding); >+ if (finallyStatus != FlowInfo.UNKNOWN) >+ newStatus = finallyStatus; >+ } >+ } >+ allocation.closeTracker.innerTracker = innerTracker; >+ innerTracker.outerTracker = allocation.closeTracker; >+ flowInfo.markNullStatus(allocation.closeTracker.binding, newStatus); >+ if (newStatus != FlowInfo.NULL) { >+ // propagate results from a finally block also into nested resources: >+ FakedTrackingVariable currentTracker = innerTracker; >+ while (currentTracker != null) { >+ flowInfo.markNullStatus(currentTracker.binding, newStatus); >+ currentTracker.globalClosingState |= allocation.closeTracker.globalClosingState; >+ currentTracker = currentTracker.innerTracker; >+ } >+ } >+ return; // keep chaining wrapper (by avoiding to fall through to removeTrackingVar below) >+ } else { >+ if (!isAnyCloseable(allocation.arguments[0].resolvedType)) { >+ isWrapper = false; // argument is not closeable >+ } >+ } >+ } else { >+ isWrapper = false; // no argument >+ } >+ // successful wrapper detection has exited above, let's see why that failed >+ if (isWrapper) { >+ // remove unnecessary attempts (wrapper has no relevant inner) >+ if (allocation.closeTracker != null) { >+ scope.removeTrackingVar(allocation.closeTracker); >+ allocation.closeTracker = null; >+ } >+ } else { >+ // allocation does not provide a resource as the first argument -> don't treat as a wrapper >+ handleRegularResource(scope, flowInfo, allocation); >+ } >+ } else { // regular resource >+ handleRegularResource(scope, flowInfo, allocation); >+ } >+ } >+ >+ private static void handleRegularResource(BlockScope scope, FlowInfo flowInfo, AllocationExpression allocation) { >+ FakedTrackingVariable presetTracker = allocation.closeTracker; >+ if (presetTracker != null && presetTracker.originalBinding != null) { >+ // the current assignment forgets a previous resource in the LHS, may cause a leak >+ // report now because handleResourceAssignment can't distinguish this from a self-wrap situation >+ int closeStatus = flowInfo.nullStatus(presetTracker.binding); >+ if (closeStatus != FlowInfo.NON_NULL // old resource was not closed >+ && closeStatus != FlowInfo.UNKNOWN // old resource had some flow information >+ && !flowInfo.isDefinitelyNull(presetTracker.originalBinding) // old resource was not null >+ && !(presetTracker.currentAssignment instanceof LocalDeclaration)) // forgetting old val in local decl is syntactically impossible >+ allocation.closeTracker.recordErrorLocation(presetTracker.currentAssignment, closeStatus); >+ } else { >+ allocation.closeTracker = new FakedTrackingVariable(scope, allocation); // no local available, closeable is unassigned >+ } >+ flowInfo.markAsDefinitelyNull(allocation.closeTracker.binding); >+ } >+ >+ /** Find an existing tracking variable for the argument of an allocation for a resource wrapper. */ >+ private static FakedTrackingVariable findCloseTracker(BlockScope scope, FlowInfo flowInfo, Expression arg) >+ { >+ while (arg instanceof Assignment) { >+ Assignment assign = (Assignment)arg; >+ LocalVariableBinding innerLocal = assign.localVariableBinding(); >+ if (innerLocal != null) { >+ // nested assignment has already been processed >+ return innerLocal.closeTracker; >+ } else { >+ arg = assign.expression; // unwrap assignment and fall through >+ } >+ } >+ if (arg instanceof SingleNameReference) { >+ // is allocation arg a reference to an existing closeable? >+ LocalVariableBinding local = arg.localVariableBinding(); >+ if (local != null) { >+ return local.closeTracker; >+ } >+ } else if (arg instanceof AllocationExpression) { >+ // nested allocation >+ return ((AllocationExpression)arg).closeTracker; >+ } >+ return null; // not a tracked expression >+ } >+ >+ /** >+ * Check if the rhs of an assignment or local declaration is an (Auto)Closeable. >+ * If so create or re-use a tracking variable, and wire and initialize everything. >+ * @param scope scope containing the assignment >+ * @param upstreamInfo info without analysis of the rhs, use this to determine the status of a resource being disconnected >+ * @param flowInfo info with analysis of the rhs, use this for recording resource status because this will be passed downstream >+ * @param location where to report warnigs/errors against >+ * @param rhs the right hand side of the assignment, this expression is to be analyzed. >+ * The caller has already checked that the rhs is either of a closeable type or null. >+ * @param local the local variable into which the rhs is being assigned >+ */ >+ public static void handleResourceAssignment(BlockScope scope, FlowInfo upstreamInfo, FlowInfo flowInfo, ASTNode location, Expression rhs, LocalVariableBinding local) >+ { >+ // does the LHS (local) already have a tracker, indicating we may leak a resource by the assignment? >+ FakedTrackingVariable previousTracker = null; >+ FakedTrackingVariable disconnectedTracker = null; >+ if (local.closeTracker != null) { >+ // assigning to a variable already holding an AutoCloseable, has it been closed before? >+ previousTracker = local.closeTracker; >+ int nullStatus = upstreamInfo.nullStatus(local); >+ if (nullStatus != FlowInfo.NULL && nullStatus != FlowInfo.UNKNOWN) // only if previous value may be relevant >+ disconnectedTracker = previousTracker; // report error below, unless we have a self-wrap assignment >+ } >+ >+ rhsAnalyis: >+ if (rhs.resolvedType != TypeBinding.NULL) { >+ // new value is AutoCloseable, start tracking, possibly re-using existing tracker var: >+ FakedTrackingVariable rhsTrackVar = getCloseTrackingVariable(rhs); >+ if (rhsTrackVar != null) { // 1. if RHS has a tracking variable... >+ if (local.closeTracker == null) { >+ // null shouldn't occur but let's play safe: >+ if (rhsTrackVar.originalBinding != null) >+ local.closeTracker = rhsTrackVar; // a.: let fresh LHS share it >+ if (rhsTrackVar.currentAssignment == location) { >+ // pre-set tracker from lhs - passed from outside? >+ // now it's a fresh resource >+ rhsTrackVar.globalClosingState &= ~(SHARED_WITH_OUTSIDE|OWNED_BY_OUTSIDE); >+ } >+ } else { >+ if (rhs instanceof AllocationExpression) { >+ if (rhsTrackVar == disconnectedTracker) >+ return; // b.: self wrapper: res = new Wrap(res); -> done! >+ if (local.closeTracker == rhsTrackVar >+ && ((rhsTrackVar.globalClosingState & OWNED_BY_OUTSIDE) != 0)) { >+ // c.: assigning a fresh resource (pre-connected alloc) >+ // to a local previously holding an alien resource -> start over >+ local.closeTracker = new FakedTrackingVariable(local, location); >+ flowInfo.markAsDefinitelyNull(local.closeTracker.binding); >+ // still check disconnectedTracker below >+ break rhsAnalyis; >+ } >+ } >+ local.closeTracker = rhsTrackVar; // d.: conflicting LHS and RHS, proceed with recordErrorLocation below >+ } >+ // keep close-status of RHS unchanged across this assignment >+ } else if (previousTracker != null) { // 2. re-use tracking variable from the LHS? >+ // re-assigning from a fresh value, mark as not-closed again: >+ if ((previousTracker.globalClosingState & (SHARED_WITH_OUTSIDE|OWNED_BY_OUTSIDE)) == 0) >+ flowInfo.markAsDefinitelyNull(previousTracker.binding); >+ local.closeTracker = analyseCloseableExpression(flowInfo, local, location, rhs, previousTracker); >+ } else { // 3. no re-use, create a fresh tracking variable: >+ rhsTrackVar = analyseCloseableExpression(flowInfo, local, location, rhs, null); >+ if (rhsTrackVar != null) { >+ local.closeTracker = rhsTrackVar; >+ // a fresh resource, mark as not-closed: >+ if ((rhsTrackVar.globalClosingState & (SHARED_WITH_OUTSIDE|OWNED_BY_OUTSIDE)) == 0) >+ flowInfo.markAsDefinitelyNull(rhsTrackVar.binding); >+// TODO(stephan): this might be useful, but I could not find a test case for it: >+// if (flowContext.initsOnFinally != null) >+// flowContext.initsOnFinally.markAsDefinitelyNonNull(trackerBinding); >+ } >+ } >+ } >+ >+ if (disconnectedTracker != null) { >+ if (disconnectedTracker.innerTracker != null && disconnectedTracker.innerTracker.binding.declaringScope == scope) { >+ // discard tracker for the wrapper but keep the inner: >+ disconnectedTracker.innerTracker.outerTracker = null; >+ scope.pruneWrapperTrackingVar(disconnectedTracker); >+ } else { >+ int upstreamStatus = upstreamInfo.nullStatus(disconnectedTracker.binding); >+ if (upstreamStatus != FlowInfo.NON_NULL) >+ disconnectedTracker.recordErrorLocation(location, upstreamStatus); >+ } >+ } >+ } >+ /** >+ * Analyze structure of a closeable expression, matching (chained) resources against our white lists. >+ * @param flowInfo where to record close status >+ * @param local local variable to which the closeable is being assigned >+ * @param location where to flag errors/warnings against >+ * @param expression expression to be analyzed >+ * @param previousTracker when analyzing a re-assignment we may already have a tracking variable for local, >+ * which we should then re-use >+ * @return a tracking variable associated with local or null if no need to track >+ */ >+ private static FakedTrackingVariable analyseCloseableExpression(FlowInfo flowInfo, LocalVariableBinding local, >+ ASTNode location, Expression expression, FakedTrackingVariable previousTracker) >+ { >+ // unwrap uninteresting nodes: >+ while (true) { >+ if (expression instanceof Assignment) >+ expression = ((Assignment)expression).expression; >+ else if (expression instanceof CastExpression) >+ expression = ((CastExpression) expression).expression; >+ else >+ break; >+ } >+ >+ // analyze by node type: >+ if (expression instanceof AllocationExpression) { >+ // allocation expressions already have their tracking variables analyzed by analyseCloseableAllocation(..) >+ FakedTrackingVariable tracker = ((AllocationExpression) expression).closeTracker; >+ if (tracker != null && tracker.originalBinding == null) { >+ // tracker without original binding (unassigned closeable) shouldn't reach here but let's play safe >+ return null; >+ } >+ return tracker; >+ } else if (expression instanceof MessageSend >+ || expression instanceof ArrayReference) >+ { >+ // we *might* be responsible for the resource obtained >+ FakedTrackingVariable tracker = new FakedTrackingVariable(local, location); >+ tracker.globalClosingState |= SHARED_WITH_OUTSIDE; >+ flowInfo.markPotentiallyNullBit(tracker.binding); // shed some doubt >+ return tracker; >+ } else if ( >+ (expression.bits & RestrictiveFlagMASK) == Binding.FIELD >+ ||((expression instanceof QualifiedNameReference) >+ && ((QualifiedNameReference) expression).isFieldAccess())) >+ { >+ // responsibility for this resource probably lies at a higher level >+ FakedTrackingVariable tracker = new FakedTrackingVariable(local, location); >+ tracker.globalClosingState |= OWNED_BY_OUTSIDE; >+ // leave state as UNKNOWN, the bit OWNED_BY_OUTSIDE will prevent spurious warnings >+ return tracker; >+ } >+ >+ if (expression.resolvedType instanceof ReferenceBinding) { >+ ReferenceBinding resourceType = (ReferenceBinding) expression.resolvedType; >+ if (resourceType.hasTypeBit(TypeIds.BitResourceFreeCloseable)) { >+ // (a) resource-free closeable: -> null >+ return null; >+ } >+ } >+ if (local.closeTracker != null) >+ // (c): inner has already been analyzed: -> re-use track var >+ return local.closeTracker; >+ FakedTrackingVariable newTracker = new FakedTrackingVariable(local, location); >+ LocalVariableBinding rhsLocal = expression.localVariableBinding(); >+ if (rhsLocal != null && rhsLocal.isParameter()) { >+ newTracker.globalClosingState |= OWNED_BY_OUTSIDE; >+ } >+ return newTracker; >+ } >+ >+ public static void cleanUpAfterAssignment(BlockScope currentScope, int lhsBits, Expression expression) { >+ // remove all remaining track vars with no original binding >+ >+ // unwrap uninteresting nodes: >+ while (true) { >+ if (expression instanceof Assignment) >+ expression = ((Assignment)expression).expression; >+ else if (expression instanceof CastExpression) >+ expression = ((CastExpression) expression).expression; >+ else >+ break; >+ } >+ if (expression instanceof AllocationExpression) { >+ FakedTrackingVariable tracker = ((AllocationExpression) expression).closeTracker; >+ if (tracker != null && tracker.originalBinding == null) { >+ currentScope.removeTrackingVar(tracker); >+ ((AllocationExpression) expression).closeTracker = null; >+ } >+ } else { >+ // assignment passing a local into a field? >+ LocalVariableBinding local = expression.localVariableBinding(); >+ if (local != null && local.closeTracker != null && ((lhsBits & Binding.FIELD) != 0)) >+ currentScope.removeTrackingVar(local.closeTracker); // TODO: may want to use local.closeTracker.markPassedToOutside(..,true) >+ } >+ } >+ >+ /** Answer wither the given type binding is a subtype of java.lang.AutoCloseable. */ >+ public static boolean isAnyCloseable(TypeBinding typeBinding) { >+ return typeBinding instanceof ReferenceBinding >+ && ((ReferenceBinding)typeBinding).hasTypeBit(TypeIds.BitAutoCloseable|TypeIds.BitCloseable); >+ } >+ >+ public int findMostSpecificStatus(FlowInfo flowInfo, BlockScope currentScope, BlockScope locationScope) { >+ int status = FlowInfo.UNKNOWN; >+ FakedTrackingVariable currentTracker = this; >+ // loop as to consider wrappers (per white list) encapsulating an inner resource. >+ while (currentTracker != null) { >+ LocalVariableBinding currentVar = currentTracker.binding; >+ int currentStatus = getNullStatusAggressively(currentVar, flowInfo); >+ if (locationScope != null) // only check at method exit points >+ currentStatus = mergeCloseStatus(locationScope, currentStatus, currentVar, currentScope); >+ if (currentStatus == FlowInfo.NON_NULL) { >+ status = currentStatus; >+ break; // closed -> stop searching >+ } else if (status == FlowInfo.NULL || status == FlowInfo.UNKNOWN) { >+ status = currentStatus; // improved although not yet safe -> keep searching for better >+ } >+ currentTracker = currentTracker.innerTracker; >+ } >+ return status; >+ } >+ >+ /** >+ * Get the null status looking even into unreachable flows >+ * @param local >+ * @param flowInfo >+ * @return one of the constants FlowInfo.{NULL,POTENTIALLY_NULL,POTENTIALLY_NON_NULL,NON_NULL}. >+ */ >+ private int getNullStatusAggressively(LocalVariableBinding local, FlowInfo flowInfo) { >+ int reachMode = flowInfo.reachMode(); >+ int status = 0; >+ try { >+ // unreachable flowInfo is too shy in reporting null-issues, temporarily forget reachability: >+ if (reachMode != FlowInfo.REACHABLE) >+ flowInfo.tagBits &= ~FlowInfo.UNREACHABLE; >+ status = flowInfo.nullStatus(local); >+ } finally { >+ // reset >+ flowInfo.tagBits |= reachMode; >+ } >+ // at this point some combinations are not useful so flatten to a single bit: >+ if ((status & FlowInfo.NULL) != 0) { >+ if ((status & (FlowInfo.NON_NULL | FlowInfo.POTENTIALLY_NON_NULL)) != 0) >+ return FlowInfo.POTENTIALLY_NULL; // null + doubt = pot null >+ return FlowInfo.NULL; >+ } else if ((status & FlowInfo.NON_NULL) != 0) { >+ if ((status & FlowInfo.POTENTIALLY_NULL) != 0) >+ return FlowInfo.POTENTIALLY_NULL; // non-null + doubt = pot null >+ return FlowInfo.NON_NULL; >+ } else if ((status & FlowInfo.POTENTIALLY_NULL) != 0) >+ return FlowInfo.POTENTIALLY_NULL; >+ return status; >+ } >+ >+ public int mergeCloseStatus(BlockScope currentScope, int status, LocalVariableBinding local, BlockScope outerScope) { >+ // get the most suitable null status representing whether resource 'binding' has been closed >+ // start at 'currentScope' and potentially travel out until 'outerScope' >+ // at each scope consult any recorded 'finallyInfo'. >+ if (status != FlowInfo.NON_NULL) { >+ if (currentScope.finallyInfo != null) { >+ int finallyStatus = currentScope.finallyInfo.nullStatus(local); >+ if (finallyStatus == FlowInfo.NON_NULL) >+ return finallyStatus; >+ if (finallyStatus != FlowInfo.NULL) // neither is NON_NULL, but not both are NULL => call it POTENTIALLY_NULL >+ status = FlowInfo.POTENTIALLY_NULL; >+ } >+ if (currentScope != outerScope && currentScope.parent instanceof BlockScope) >+ return mergeCloseStatus(((BlockScope) currentScope.parent), status, local, outerScope); >+ } >+ return status; >+ } >+ >+ /** Mark that this resource is closed locally. */ >+ public void markClose(FlowInfo flowInfo, FlowContext flowContext) { >+ FakedTrackingVariable current = this; >+ do { >+ flowInfo.markAsDefinitelyNonNull(current.binding); >+ current.globalClosingState |= CLOSE_SEEN; >+//TODO(stephan): this might be useful, but I could not find a test case for it: >+ if (flowContext.initsOnFinally != null) >+ flowContext.initsOnFinally.markAsDefinitelyNonNull(this.binding); >+ current = current.innerTracker; >+ } while (current != null); >+ } >+ >+ /** Mark that this resource is closed from a nested method (inside a local class). */ >+ public void markClosedInNestedMethod() { >+ this.globalClosingState |= CLOSED_IN_NESTED_METHOD; >+ } >+ >+ /** >+ * Mark that this resource is passed to some outside code >+ * (as argument to a method/ctor call or as a return value from the current method), >+ * and thus should be considered as potentially closed. >+ * @param owned should the resource be considered owned by some outside? >+ */ >+ public static FlowInfo markPassedToOutside(BlockScope scope, Expression expression, FlowInfo flowInfo, boolean owned) { >+ >+ FakedTrackingVariable trackVar = getCloseTrackingVariable(expression); >+ if (trackVar != null) { >+ // insert info that the tracked resource *may* be closed (by the target method, i.e.) >+ FlowInfo infoResourceIsClosed = owned ? flowInfo : flowInfo.copy(); >+ int flag = owned ? OWNED_BY_OUTSIDE : SHARED_WITH_OUTSIDE; >+ do { >+ trackVar.globalClosingState |= flag; >+ if (scope.methodScope() != trackVar.methodScope) >+ trackVar.globalClosingState |= CLOSED_IN_NESTED_METHOD; >+ infoResourceIsClosed.markAsDefinitelyNonNull(trackVar.binding); >+ } while ((trackVar = trackVar.innerTracker) != null); >+ if (owned) { >+ return infoResourceIsClosed; // don't let downstream signal any problems on this flow >+ } else { >+ return FlowInfo.conditional(flowInfo, infoResourceIsClosed); // only report potential problems on this flow >+ } >+ } >+ return flowInfo; >+ } >+ >+ /** >+ * Pick tracking variables from 'varsOfScope' to establish a proper order of processing: >+ * As much as possible pick wrapper resources before their inner resources. >+ * Also consider cases of wrappers and their inners being declared at different scopes. >+ */ >+ public static FakedTrackingVariable pickVarForReporting(Set varsOfScope, BlockScope scope, boolean atExit) { >+ if (varsOfScope.isEmpty()) return null; >+ FakedTrackingVariable trackingVar = (FakedTrackingVariable) varsOfScope.iterator().next(); >+ while (trackingVar.outerTracker != null) { >+ // resource is wrapped, is wrapper defined in this scope? >+ if (varsOfScope.contains(trackingVar.outerTracker)) { >+ // resource from same scope, travel up the wrapper chain >+ trackingVar = trackingVar.outerTracker; >+ } else if (atExit) { >+ // at an exit point we report against inner despite a wrapper that may/may not be closed later >+ break; >+ } else { >+ BlockScope outerTrackerScope = trackingVar.outerTracker.binding.declaringScope; >+ if (outerTrackerScope == scope) { >+ // outerTracker is from same scope and already processed -> pick trackingVar now >+ break; >+ } else { >+ // outer resource is from other (outer?) scope >+ Scope currentScope = scope; >+ while ((currentScope = currentScope.parent) instanceof BlockScope) { >+ if (outerTrackerScope == currentScope) { >+ // at end of block pass responsibility for inner resource to outer scope holding a wrapper >+ varsOfScope.remove(trackingVar); // drop this one >+ // pick a next candidate: >+ return pickVarForReporting(varsOfScope, scope, atExit); >+ } >+ } >+ break; // not parent owned -> pick this var >+ } >+ } >+ } >+ varsOfScope.remove(trackingVar); >+ return trackingVar; >+ } >+ >+ /** >+ * Answer true if we know for sure that no resource is bound to this variable >+ * at the point of 'flowInfo'. >+ */ >+ public boolean hasDefinitelyNoResource(FlowInfo flowInfo) { >+ if (this.originalBinding == null) return false; // shouldn't happen but keep quiet. >+ if (flowInfo.isDefinitelyNull(this.originalBinding)) { >+ return true; >+ } >+ if (!(flowInfo.isDefinitelyAssigned(this.originalBinding) >+ || flowInfo.isPotentiallyAssigned(this.originalBinding))) { >+ return true; >+ } >+ return false; >+ } >+ >+ public boolean isClosedInFinallyOfEnclosing(BlockScope scope) { >+ BlockScope currentScope = scope; >+ while (true) { >+ if (currentScope.finallyInfo != null >+ && currentScope.finallyInfo.isDefinitelyNonNull(this.binding)) { >+ return true; // closed in enclosing finally >+ } >+ if (!(currentScope.parent instanceof BlockScope)) { >+ return false; >+ } >+ currentScope = (BlockScope) currentScope.parent; >+ } >+ } >+ /** >+ * If current is the same as 'returnedResource' or a wrapper thereof, >+ * mark as reported and return true, otherwise false. >+ */ >+ public boolean isResourceBeingReturned(FakedTrackingVariable returnedResource) { >+ FakedTrackingVariable current = this; >+ do { >+ if (current == returnedResource) { >+ this.globalClosingState |= REPORTED_DEFINITIVE_LEAK; >+ return true; >+ } >+ current = current.innerTracker; >+ } while (current != null); >+ return false; >+ } >+ >+ public void recordErrorLocation(ASTNode location, int nullStatus) { >+ if ((this.globalClosingState & OWNED_BY_OUTSIDE) != 0) { >+ return; >+ } >+ if (this.recordedLocations == null) >+ this.recordedLocations = new HashMap(); >+ this.recordedLocations.put(location, new Integer(nullStatus)); >+ } >+ >+ public boolean reportRecordedErrors(Scope scope, int mergedStatus) { >+ FakedTrackingVariable current = this; >+ while (current.globalClosingState == 0) { >+ current = current.innerTracker; >+ if (current == null) { >+ // no relevant state found -> report: >+ reportError(scope.problemReporter(), null, mergedStatus); >+ return true; >+ } >+ } >+ boolean hasReported = false; >+ if (this.recordedLocations != null) { >+ Iterator locations = this.recordedLocations.entrySet().iterator(); >+ int reportFlags = 0; >+ while (locations.hasNext()) { >+ Map.Entry entry = (Entry) locations.next(); >+ reportFlags |= reportError(scope.problemReporter(), (ASTNode)entry.getKey(), ((Integer)entry.getValue()).intValue()); >+ hasReported = true; >+ } >+ if (reportFlags != 0) { >+ // after all locations have been reported, mark as reported to prevent duplicate report via an outer wrapper >+ current = this; >+ do { >+ current.globalClosingState |= reportFlags; >+ } while ((current = current.innerTracker) != null); >+ } >+ } >+ return hasReported; >+ } >+ >+ public int reportError(ProblemReporter problemReporter, ASTNode location, int nullStatus) { >+ if ((this.globalClosingState & OWNED_BY_OUTSIDE) != 0) { >+ return 0; // TODO: should we still propagate some flags?? >+ } >+ // which degree of problem? >+ boolean isPotentialProblem = false; >+ if (nullStatus == FlowInfo.NULL) { >+ if ((this.globalClosingState & CLOSED_IN_NESTED_METHOD) != 0) >+ isPotentialProblem = true; >+ } else if ((nullStatus & (FlowInfo.POTENTIALLY_NULL|FlowInfo.POTENTIALLY_NON_NULL)) != 0) { >+ isPotentialProblem = true; >+ } >+ // report: >+ if (isPotentialProblem) { >+ if ((this.globalClosingState & (REPORTED_POTENTIAL_LEAK|REPORTED_DEFINITIVE_LEAK)) != 0) >+ return 0; >+ problemReporter.potentiallyUnclosedCloseable(this, location); >+ } else { >+ if ((this.globalClosingState & (REPORTED_DEFINITIVE_LEAK)) != 0) >+ return 0; >+ problemReporter.unclosedCloseable(this, location); >+ } >+ // propagate flag to inners: >+ int reportFlag = isPotentialProblem ? REPORTED_POTENTIAL_LEAK : REPORTED_DEFINITIVE_LEAK; >+ if (location == null) { // if location != null flags will be set after the loop over locations >+ FakedTrackingVariable current = this; >+ do { >+ current.globalClosingState |= reportFlag; >+ } while ((current = current.innerTracker) != null); >+ } >+ return reportFlag; >+ } >+ >+ public void reportExplicitClosing(ProblemReporter problemReporter) { >+ if ((this.globalClosingState & (OWNED_BY_OUTSIDE|REPORTED_EXPLICIT_CLOSE)) == 0) { // can't use t-w-r for OWNED_BY_OUTSIDE >+ this.globalClosingState |= REPORTED_EXPLICIT_CLOSE; >+ problemReporter.explicitlyClosedAutoCloseable(this); >+ } >+ } >+ >+ public void resetReportingBits() { >+ FakedTrackingVariable current = this; >+ do { >+ current.globalClosingState &= ~(REPORTED_POTENTIAL_LEAK|REPORTED_DEFINITIVE_LEAK); >+ current = current.innerTracker; >+ } while (current != null); >+ } >+} >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java >index 30ab54e..3dd3417 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java >@@ -123,6 +123,12 @@ > return (this.modifiers & ClassFileConstants.AccStatic) != 0; > } > >+public boolean isFinal() { >+ if (this.binding != null) >+ return this.binding.isFinal(); >+ return (this.modifiers & ClassFileConstants.AccFinal) != 0; >+} >+ > public StringBuffer printStatement(int indent, StringBuffer output) { > if (this.javadoc != null) { > this.javadoc.print(indent, output); >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java >index 41e569b..498a814 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java >@@ -7,7 +7,9 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >- * Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE >+ * Stephan Herrmann - Contributions for >+ * bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE >+ * bug 349326 - [1.7] new warning for missing try-with-resources > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >@@ -138,7 +140,7 @@ > actionInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD); > } > } >- if (this.action.complainIfUnreachable(actionInfo, this.scope, initialComplaintLevel) < Statement.COMPLAINED_UNREACHABLE) { >+ if (this.action.complainIfUnreachable(actionInfo, this.scope, initialComplaintLevel, true) < Statement.COMPLAINED_UNREACHABLE) { > actionInfo = this.action.analyseCode(this.scope, loopingContext, actionInfo).unconditionalInits(); > } > >@@ -215,6 +217,17 @@ > exitBranch, > isConditionOptimizedFalse, > !isConditionTrue /*for(;;){}while(true); unreachable(); */); >+ // Variables initialized only for the purpose of the for loop can be removed for further flow info >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=359495 >+ if (this.initializations != null) { >+ for (int i = 0; i < this.initializations.length; i++) { >+ Statement init = this.initializations[i]; >+ if (init instanceof LocalDeclaration) { >+ LocalVariableBinding binding = ((LocalDeclaration) init).binding; >+ mergedInfo.resetAssignmentInfo(binding); >+ } >+ } >+ } > this.mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo); > return mergedInfo; > } >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java >index 17693c8..78fef08 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,6 +7,9 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contribution for >+ * bug 349326 - [1.7] new warning for missing try-with-resources >+ * bug 370930 - NonNull annotation not considered for enhanced for loops > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >@@ -25,6 +28,7 @@ > import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding; > import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding; > import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; >+import org.eclipse.jdt.internal.compiler.lookup.TagBits; > import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; > > public class ForeachStatement extends Statement { >@@ -82,9 +86,10 @@ > this.collection.checkNPE(currentScope, flowContext, flowInfo); > flowInfo = this.elementVariable.analyseCode(this.scope, flowContext, flowInfo); > FlowInfo condInfo = this.collection.analyseCode(this.scope, flowContext, flowInfo.copy()); >+ LocalVariableBinding elementVarBinding = this.elementVariable.binding; > > // element variable will be assigned when iterating >- condInfo.markAsDefinitelyAssigned(this.elementVariable.binding); >+ condInfo.markAsDefinitelyAssigned(elementVarBinding); > > this.postCollectionInitStateIndex = currentScope.methodScope().recordInitializationStates(condInfo); > >@@ -94,18 +99,28 @@ > this.continueLabel, this.scope); > UnconditionalFlowInfo actionInfo = > condInfo.nullInfoLessUnconditionalCopy(); >- actionInfo.markAsDefinitelyUnknown(this.elementVariable.binding); >+ actionInfo.markAsDefinitelyUnknown(elementVarBinding); >+ if (currentScope.compilerOptions().isAnnotationBasedNullAnalysisEnabled) { >+ // this currently produces an unavoidable warning against all @NonNull element vars: >+ int nullStatus = this.elementVariable.checkAssignmentAgainstNullAnnotation(currentScope, flowContext, >+ elementVarBinding, FlowInfo.UNKNOWN, this.collection); >+ // TODO (stephan): once we have JSR 308 fetch nullStatus from the collection element type >+ // and feed the result into the above check (instead of FlowInfo.UNKNOWN) >+ if ((elementVarBinding.type.tagBits & TagBits.IsBaseType) == 0) { >+ actionInfo.markNullStatus(elementVarBinding, nullStatus); >+ } >+ } > FlowInfo exitBranch; > if (!(this.action == null || (this.action.isEmptyBlock() > && currentScope.compilerOptions().complianceLevel <= ClassFileConstants.JDK1_3))) { > >- if (this.action.complainIfUnreachable(actionInfo, this.scope, initialComplaintLevel) < Statement.COMPLAINED_UNREACHABLE) { >+ if (this.action.complainIfUnreachable(actionInfo, this.scope, initialComplaintLevel, true) < Statement.COMPLAINED_UNREACHABLE) { > actionInfo = this.action.analyseCode(this.scope, loopingContext, actionInfo).unconditionalCopy(); > } > > // code generation can be optimized when no need to continue in the loop > exitBranch = flowInfo.unconditionalCopy(). >- addInitializationsFrom(condInfo.initsWhenFalse()); >+ addNullInfoFrom(condInfo.initsWhenFalse()); > // TODO (maxime) no need to test when false: can optimize (same for action being unreachable above) > if ((actionInfo.tagBits & loopingContext.initsOnContinue.tagBits & > FlowInfo.UNREACHABLE_OR_DEAD) != 0) { >@@ -128,7 +143,7 @@ > switch(this.kind) { > case ARRAY : > if (!hasEmptyAction >- || this.elementVariable.binding.resolvedPosition != -1) { >+ || elementVarBinding.resolvedPosition != -1) { > this.collectionVariable.useFlag = LocalVariableBinding.USED; > if (this.continueLabel != null) { > this.indexVariable.useFlag = LocalVariableBinding.USED; >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java >index 2f3b1a7..5545720 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java >@@ -7,7 +7,9 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >- * Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE >+ * Stephan Herrmann - Contributions for >+ * bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE >+ * bug 349326 - [1.7] new warning for missing try-with-resources > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >@@ -84,12 +86,13 @@ > // No need if the whole if-else construct itself lies in unreachable code > this.bits |= ASTNode.IsElseStatementUnreachable; > } >+ boolean reportDeadCodeForKnownPattern = !isKnowDeadCodePattern(this.condition) || currentScope.compilerOptions().reportDeadCodeInTrivialIfStatement; > if (this.thenStatement != null) { > // Save info for code gen > this.thenInitStateIndex = currentScope.methodScope().recordInitializationStates(thenFlowInfo); > if (isConditionOptimizedFalse || ((this.bits & ASTNode.IsThenStatementUnreachable) != 0)) { >- if (!isKnowDeadCodePattern(this.condition) || currentScope.compilerOptions().reportDeadCodeInTrivialIfStatement) { >- this.thenStatement.complainIfUnreachable(thenFlowInfo, currentScope, initialComplaintLevel); >+ if (reportDeadCodeForKnownPattern) { >+ this.thenStatement.complainIfUnreachable(thenFlowInfo, currentScope, initialComplaintLevel, false); > } else { > // its a known coding pattern which should be tolerated by dead code analysis > // according to isKnowDeadCodePattern() >@@ -114,8 +117,8 @@ > // Save info for code gen > this.elseInitStateIndex = currentScope.methodScope().recordInitializationStates(elseFlowInfo); > if (isConditionOptimizedTrue || ((this.bits & ASTNode.IsElseStatementUnreachable) != 0)) { >- if (!isKnowDeadCodePattern(this.condition) || currentScope.compilerOptions().reportDeadCodeInTrivialIfStatement) { >- this.elseStatement.complainIfUnreachable(elseFlowInfo, currentScope, initialComplaintLevel); >+ if (reportDeadCodeForKnownPattern) { >+ this.elseStatement.complainIfUnreachable(elseFlowInfo, currentScope, initialComplaintLevel, false); > } else { > // its a known coding pattern which should be tolerated by dead code analysis > // according to isKnowDeadCodePattern() >@@ -124,6 +127,8 @@ > } > elseFlowInfo = this.elseStatement.analyseCode(currentScope, flowContext, elseFlowInfo); > } >+ // process AutoCloseable resources closed in only one branch: >+ currentScope.correlateTrackingVarsIfElse(thenFlowInfo, elseFlowInfo); > // merge THEN & ELSE initializations > FlowInfo mergedInfo = FlowInfo.mergedOptimizedBranchesIfElse( > thenFlowInfo, >@@ -132,7 +137,8 @@ > isConditionOptimizedFalse, > true /*if(true){ return; } fake-reachable(); */, > flowInfo, >- this); >+ this, >+ reportDeadCodeForKnownPattern); > this.mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo); > return mergedInfo; > } >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java >index 7606dc4..ca65c04 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,10 +7,14 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >- * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for >- * bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE >- * bug 292478 - Report potentially null across variable assignment >- * bug 335093 - [compiler][null] minimal hook for future null annotation support >+ * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for >+ * bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE >+ * bug 292478 - Report potentially null across variable assignment >+ * bug 335093 - [compiler][null] minimal hook for future null annotation support >+ * bug 349326 - [1.7] new warning for missing try-with-resources >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 358903 - Filter practically unimportant resource leak warnings >+ * bug 370639 - [compiler][resource] restore the default for resource leak warnings > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >@@ -72,10 +76,27 @@ > this.initialization.checkNPE(currentScope, flowContext, flowInfo); > } > >+ FlowInfo preInitInfo = null; >+ boolean shouldAnalyseResource = this.binding != null >+ && flowInfo.reachMode() == FlowInfo.REACHABLE >+ && FakedTrackingVariable.isAnyCloseable(this.initialization.resolvedType) >+ && currentScope.compilerOptions().analyseResourceLeaks; >+ if (shouldAnalyseResource) { >+ preInitInfo = flowInfo.unconditionalCopy(); >+ // analysis of resource leaks needs additional context while analyzing the RHS: >+ FakedTrackingVariable.preConnectTrackerAcrossAssignment(this, this.binding, this.initialization); >+ } >+ > flowInfo = > this.initialization > .analyseCode(currentScope, flowContext, flowInfo) > .unconditionalInits(); >+ >+ if (shouldAnalyseResource) >+ FakedTrackingVariable.handleResourceAssignment(currentScope, preInitInfo, flowInfo, this, this.initialization, this.binding); >+ else >+ FakedTrackingVariable.cleanUpAfterAssignment(currentScope, Binding.LOCAL, this.initialization); >+ > int nullStatus = this.initialization.nullStatus(flowInfo); > if (!flowInfo.isDefinitelyAssigned(this.binding)){// for local variable debug attributes > this.bits |= FirstAssignmentToLocal; >@@ -83,7 +104,7 @@ > this.bits &= ~FirstAssignmentToLocal; // int i = (i = 0); > } > flowInfo.markAsDefinitelyAssigned(this.binding); >- nullStatus = checkAgainstNullAnnotation(currentScope, this.binding, nullStatus); >+ nullStatus = checkAssignmentAgainstNullAnnotation(currentScope, flowContext, this.binding, nullStatus, this.initialization); > if ((this.binding.type.tagBits & TagBits.IsBaseType) == 0) { > flowInfo.markNullStatus(this.binding, nullStatus); > // no need to inform enclosing try block since its locals won't get >@@ -133,9 +154,8 @@ > this.initialization.generateCode(currentScope, codeStream, true); > // 26903, need extra cast to store null in array local var > if (this.binding.type.isArrayType() >- && (this.initialization.resolvedType == TypeBinding.NULL // arrayLoc = null >- || ((this.initialization instanceof CastExpression) // arrayLoc = (type[])null >- && (((CastExpression)this.initialization).innermostCastedExpression().resolvedType == TypeBinding.NULL)))){ >+ && ((this.initialization instanceof CastExpression) // arrayLoc = (type[])null >+ && (((CastExpression)this.initialization).innermostCastedExpression().resolvedType == TypeBinding.NULL))){ > codeStream.checkcast(this.binding.type); > } > codeStream.store(this.binding, false); >@@ -185,7 +205,7 @@ > if ((this.modifiers & ClassFileConstants.AccFinal)!= 0 && this.initialization == null) { > this.modifiers |= ExtraCompilerModifiers.AccBlankFinal; > } >- this.binding = new LocalVariableBinding(this, variableType, this.modifiers, false); >+ this.binding = new LocalVariableBinding(this, variableType, this.modifiers, false /*isArgument*/); > scope.addLocalVariable(this.binding); > this.binding.setConstant(Constant.NotAConstant); > // allow to recursivelly target the binding.... >@@ -249,6 +269,7 @@ > } > // only resolve annotation at the end, for constant to be positioned before (96991) > resolveAnnotations(scope, this.annotations, this.binding); >+ scope.validateNullAnnotation(this.binding.tagBits, this.type, this.annotations); > } > > public void traverse(ASTVisitor visitor, BlockScope scope) { >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MemberValuePair.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MemberValuePair.java >index a083742..e0f7cfb 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MemberValuePair.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MemberValuePair.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,6 +7,9 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contributions for >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 365519 - editorial cleanup after bug 186342 and bug 365387 > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java >index f913302..86d0370 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -8,7 +8,12 @@ > * Contributors: > * IBM Corporation - initial API and implementation > * Nick Teryaev - fix for bug (https://bugs.eclipse.org/bugs/show_bug.cgi?id=40752) >- * Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE >+ * Stephan Herrmann - Contributions for >+ * bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE >+ * bug 349326 - [1.7] new warning for missing try-with-resources >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 358903 - Filter practically unimportant resource leak warnings >+ * bug 370639 - [compiler][resource] restore the default for resource leak warnings > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >@@ -38,6 +43,7 @@ > import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding; > import org.eclipse.jdt.internal.compiler.lookup.TagBits; > import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; >+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; > import org.eclipse.jdt.internal.compiler.lookup.TypeIds; > import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities; > >@@ -60,6 +66,19 @@ > public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { > boolean nonStatic = !this.binding.isStatic(); > flowInfo = this.receiver.analyseCode(currentScope, flowContext, flowInfo, nonStatic).unconditionalInits(); >+ // recording the closing of AutoCloseable resources: >+ boolean analyseResources = currentScope.compilerOptions().analyseResourceLeaks; >+ if (analyseResources && CharOperation.equals(TypeConstants.CLOSE, this.selector)) >+ { >+ FakedTrackingVariable trackingVariable = FakedTrackingVariable.getCloseTrackingVariable(this.receiver); >+ if (trackingVariable != null) { // null happens if receiver is not a local variable or not an AutoCloseable >+ if (trackingVariable.methodScope == currentScope.methodScope()) { >+ trackingVariable.markClose(flowInfo, flowContext); >+ } else { >+ trackingVariable.markClosedInNestedMethod(); >+ } >+ } >+ } > if (nonStatic) { > this.receiver.checkNPE(currentScope, flowContext, flowInfo); > // https://bugs.eclipse.org/bugs/show_bug.cgi?id=318682 >@@ -81,7 +100,12 @@ > this.arguments[i].checkNPE(currentScope, flowContext, flowInfo); > } > flowInfo = this.arguments[i].analyseCode(currentScope, flowContext, flowInfo).unconditionalInits(); >+ if (analyseResources) { >+ // if argument is an AutoCloseable insert info that it *may* be closed (by the target method, i.e.) >+ flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.arguments[i], flowInfo, false); >+ } > } >+ analyseArguments(currentScope, flowContext, flowInfo, this.binding, this.arguments); > } > ReferenceBinding[] thrownExceptions; > if ((thrownExceptions = this.binding.thrownExceptions) != Binding.NO_EXCEPTIONS) { >@@ -97,6 +121,11 @@ > } > manageSyntheticAccessIfNecessary(currentScope, flowInfo); > return flowInfo; >+} >+public void checkNPE(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo) { >+ super.checkNPE(scope, flowContext, flowInfo); >+ if ((nullStatus(flowInfo) & FlowInfo.POTENTIALLY_NULL) != 0) >+ scope.problemReporter().messageSendPotentialNullReference(this.binding, this); > } > /** > * @see org.eclipse.jdt.internal.compiler.ast.Expression#computeConversion(org.eclipse.jdt.internal.compiler.lookup.Scope, org.eclipse.jdt.internal.compiler.lookup.TypeBinding, org.eclipse.jdt.internal.compiler.lookup.TypeBinding) >@@ -251,9 +280,16 @@ > } > } > public int nullStatus(FlowInfo flowInfo) { >+ if (this.binding.isValidBinding()) { >+ // try to retrieve null status of this message send from an annotation of the called method: >+ long tagBits = this.binding.tagBits; >+ if ((tagBits & TagBits.AnnotationNonNull) != 0) >+ return FlowInfo.NON_NULL; >+ if ((tagBits & TagBits.AnnotationNullable) != 0) >+ return FlowInfo.POTENTIALLY_NULL | FlowInfo.POTENTIALLY_NON_NULL; >+ } > return FlowInfo.UNKNOWN; > } >- > /** > * @see org.eclipse.jdt.internal.compiler.ast.Expression#postConversionType(Scope) > */ >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java >index 53fade3..a488177 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,6 +7,11 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contributions for >+ * bug 349326 - [1.7] new warning for missing try-with-resources >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 365519 - editorial cleanup after bug 186342 and bug 365387 >+ * bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >@@ -15,8 +20,8 @@ > import org.eclipse.jdt.internal.compiler.CompilationResult; > import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; > import org.eclipse.jdt.internal.compiler.flow.ExceptionHandlingFlowContext; >+import org.eclipse.jdt.internal.compiler.flow.FlowContext; > import org.eclipse.jdt.internal.compiler.flow.FlowInfo; >-import org.eclipse.jdt.internal.compiler.flow.InitializationFlowContext; > import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; > import org.eclipse.jdt.internal.compiler.lookup.Binding; > import org.eclipse.jdt.internal.compiler.lookup.ClassScope; >@@ -43,7 +48,7 @@ > super(compilationResult); > } > >- public void analyseCode(ClassScope classScope, InitializationFlowContext initializationContext, FlowInfo flowInfo) { >+ public void analyseCode(ClassScope classScope, FlowContext flowContext, FlowInfo flowInfo) { > // starting of the code analysis for methods > if (this.ignoreFurtherInvestigation) > return; >@@ -71,17 +76,18 @@ > > ExceptionHandlingFlowContext methodContext = > new ExceptionHandlingFlowContext( >- initializationContext, >+ flowContext, > this, > this.binding.thrownExceptions, > null, > this.scope, > FlowInfo.DEAD_END); > >- // tag parameters as being set >+ // nullity and mark as assigned >+ analyseArguments(flowInfo); >+ > if (this.arguments != null) { > for (int i = 0, count = this.arguments.length; i < count; i++) { >- flowInfo.markAsDefinitelyAssigned(this.arguments[i].binding); > // if this method uses a type parameter declared by the declaring class, > // it can't be static. https://bugs.eclipse.org/bugs/show_bug.cgi?id=318682 > if (this.arguments[i].binding != null && (this.arguments[i].binding.type instanceof TypeVariableBinding)) { >@@ -100,7 +106,7 @@ > int complaintLevel = (flowInfo.reachMode() & FlowInfo.UNREACHABLE) == 0 ? Statement.NOT_COMPLAINED : Statement.COMPLAINED_FAKE_REACHABLE; > for (int i = 0, count = this.statements.length; i < count; i++) { > Statement stat = this.statements[i]; >- if ((complaintLevel = stat.complainIfUnreachable(flowInfo, this.scope, complaintLevel)) < Statement.COMPLAINED_UNREACHABLE) { >+ if ((complaintLevel = stat.complainIfUnreachable(flowInfo, this.scope, complaintLevel, true)) < Statement.COMPLAINED_UNREACHABLE) { > flowInfo = stat.analyseCode(this.scope, methodContext, flowInfo); > } > } >@@ -134,6 +140,7 @@ > } > > } >+ this.scope.checkUnclosedCloseables(flowInfo, null, null/*don't report against a specific location*/, null); > } catch (AbortMethod e) { > this.ignoreFurtherInvestigation = true; > } >@@ -305,4 +312,11 @@ > public TypeParameter[] typeParameters() { > return this.typeParameters; > } >+ >+ void validateNullAnnotations() { >+ super.validateNullAnnotations(); >+ // null-annotations on the return type? >+ if (this.binding != null) >+ this.scope.validateNullAnnotation(this.binding.tagBits, this.returnType, this.annotations); >+ } > } >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java >index 6818e1d..64c50b4 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,7 +7,12 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >- * Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE >+ * Stephan Herrmann - Contributions for >+ * bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE >+ * bug 349326 - [1.7] new warning for missing try-with-resources >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK >+ * bug 370639 - [compiler][resource] restore the default for resource leak warnings > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >@@ -59,6 +64,11 @@ > // analyse the enclosing instance > if (this.enclosingInstance != null) { > flowInfo = this.enclosingInstance.analyseCode(currentScope, flowContext, flowInfo); >+ } else { >+ if (this.binding.declaringClass.superclass().isMemberType() && !this.binding.declaringClass.superclass().isStatic()) { >+ // creating an anonymous type of a non-static member type without an enclosing instance of parent type >+ currentScope.resetEnclosingMethodStaticFlag(); >+ } > } > > // check captured variables are initialized in current context (26134) >@@ -71,12 +81,18 @@ > > // process arguments > if (this.arguments != null) { >+ boolean analyseResources = currentScope.compilerOptions().analyseResourceLeaks; > for (int i = 0, count = this.arguments.length; i < count; i++) { >+ if (analyseResources) { >+ // if argument is an AutoCloseable insert info that it *may* be closed (by the target method, i.e.) >+ flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.arguments[i], flowInfo, false); >+ } > flowInfo = this.arguments[i].analyseCode(currentScope, flowContext, flowInfo); > if ((this.arguments[i].implicitConversion & TypeIds.UNBOXING) != 0) { > this.arguments[i].checkNPE(currentScope, flowContext, flowInfo); > } > } >+ analyseArguments(currentScope, flowContext, flowInfo, this.binding, this.arguments); > } > > // analyse the anonymous nested type >@@ -98,6 +114,12 @@ > flowInfo.unconditionalCopy(), > currentScope); > } >+ >+ // after having analysed exceptions above start tracking newly allocated resource: >+ if (FakedTrackingVariable.isAnyCloseable(this.resolvedType) && currentScope.compilerOptions().analyseResourceLeaks) { >+ FakedTrackingVariable.analyseCloseableAllocation(currentScope, flowInfo, this); >+ } >+ > manageEnclosingInstanceAccessIfNecessary(currentScope, flowInfo); > manageSyntheticAccessIfNecessary(currentScope, flowInfo); > return flowInfo; >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java >index 1b4a530..55abfba 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,7 +7,11 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >- * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 185682 - Increment/decrement operators mark local variables as read >+ * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for >+ * bug 185682 - Increment/decrement operators mark local variables as read >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 365519 - editorial cleanup after bug 186342 and bug 365387 >+ * bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >@@ -782,6 +786,13 @@ > : type; > } > >+public boolean isFieldAccess() { >+ if (this.otherBindings != null) { >+ return true; >+ } >+ return (this.bits & ASTNode.RestrictiveFlagMASK) == Binding.FIELD; >+} >+ > public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) { > //If inlinable field, forget the access emulation, the code gen will directly target it > if (((this.bits & ASTNode.DepthMASK) == 0) || (this.constant != Constant.NotAConstant)) { >@@ -963,7 +974,11 @@ > && methodScope.lastVisibleFieldID >= 0 > && fieldBinding.id >= methodScope.lastVisibleFieldID > && (!fieldBinding.isStatic() || methodScope.isStatic)) { >- scope.problemReporter().forwardReference(this, this.indexOfFirstFieldBinding-1, fieldBinding); >+ if (methodScope.insideTypeAnnotation && fieldBinding.id == methodScope.lastVisibleFieldID) { >+ // false alarm, location is NOT a field initializer but the value in a memberValuePair >+ } else { >+ scope.problemReporter().forwardReference(this, this.indexOfFirstFieldBinding-1, fieldBinding); >+ } > } > if (isFieldUseDeprecated(fieldBinding, scope, this.indexOfFirstFieldBinding == this.tokens.length ? this.bits : 0)) { > scope.problemReporter().deprecatedField(fieldBinding, this); >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java >index b3f2ede..081503c 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,7 +7,16 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >- * Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE >+ * Stephan Herrmann - Contributions for >+ * bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE >+ * bug 349326 - [1.7] new warning for missing try-with-resources >+ * bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop) >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 365835 - [compiler][null] inconsistent error reporting. >+ * bug 365519 - editorial cleanup after bug 186342 and bug 365387 >+ * bug 358903 - Filter practically unimportant resource leak warnings >+ * bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK >+ * bug 370639 - [compiler][resource] restore the default for resource leak warnings > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >@@ -35,19 +44,32 @@ > > // lookup the label, this should answer the returnContext > >+ MethodScope methodScope = currentScope.methodScope(); > if (this.expression != null) { > flowInfo = this.expression.analyseCode(currentScope, flowContext, flowInfo); > if ((this.expression.implicitConversion & TypeIds.UNBOXING) != 0) { > this.expression.checkNPE(currentScope, flowContext, flowInfo); > } >+ if (flowInfo.reachMode() == FlowInfo.REACHABLE) >+ checkAgainstNullAnnotation(currentScope, flowContext, this.expression.nullStatus(flowInfo)); >+ if (currentScope.compilerOptions().analyseResourceLeaks) { >+ FakedTrackingVariable trackingVariable = FakedTrackingVariable.getCloseTrackingVariable(this.expression); >+ if (trackingVariable != null) { >+ if (methodScope != trackingVariable.methodScope) >+ trackingVariable.markClosedInNestedMethod(); >+ // by returning the method passes the responsibility to the caller: >+ flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.expression, flowInfo, true); >+ } >+ } > } > this.initStateIndex = >- currentScope.methodScope().recordInitializationStates(flowInfo); >+ methodScope.recordInitializationStates(flowInfo); > // compute the return sequence (running the finally blocks) > FlowContext traversedContext = flowContext; > int subCount = 0; > boolean saveValueNeeded = false; > boolean hasValueToSave = needValueStore(); >+ boolean noAutoCloseables = true; > do { > SubRoutineStatement sub; > if ((sub = traversedContext.subroutine()) != null) { >@@ -62,6 +84,11 @@ > saveValueNeeded = false; > this.bits |= ASTNode.IsAnySubRoutineEscaping; > break; >+ } >+ if (sub instanceof TryStatement) { >+ if (((TryStatement) sub).resources.length > 0) { >+ noAutoCloseables = false; >+ } > } > } > traversedContext.recordReturnFrom(flowInfo.unconditionalInits()); >@@ -79,14 +106,14 @@ > } > saveValueNeeded = true; > this.initStateIndex = >- currentScope.methodScope().recordInitializationStates(flowInfo); >+ methodScope.recordInitializationStates(flowInfo); > } > } > } else if (traversedContext instanceof InitializationFlowContext) { > currentScope.problemReporter().cannotReturnInInitializer(this); > return FlowInfo.DEAD_END; > } >- } while ((traversedContext = traversedContext.parent) != null); >+ } while ((traversedContext = traversedContext.getLocalParent()) != null); > > // resize subroutines > if ((this.subroutines != null) && (subCount != this.subroutines.length)) { >@@ -101,10 +128,31 @@ > } else { > this.saveValueVariable = null; > if (((this.bits & ASTNode.IsSynchronized) == 0) && this.expression != null && this.expression.resolvedType == TypeBinding.BOOLEAN) { >- this.expression.bits |= ASTNode.IsReturnedValue; >+ if (noAutoCloseables) { // can't abruptly return in the presence of autocloseables. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=367566 >+ this.expression.bits |= ASTNode.IsReturnedValue; >+ } > } > } >+ currentScope.checkUnclosedCloseables(flowInfo, flowContext, this, currentScope); > return FlowInfo.DEAD_END; >+} >+void checkAgainstNullAnnotation(BlockScope scope, FlowContext flowContext, int nullStatus) { >+ if (nullStatus != FlowInfo.NON_NULL) { >+ // if we can't prove non-null check against declared null-ness of the enclosing method: >+ long tagBits; >+ MethodBinding methodBinding; >+ try { >+ methodBinding = scope.methodScope().referenceMethod().binding; >+ tagBits = methodBinding.tagBits; >+ } catch (NullPointerException npe) { >+ // chain of references in try-block has several potential nulls; >+ // any null means we cannot perform the following check >+ return; >+ } >+ if ((tagBits & TagBits.AnnotationNonNull) != 0) { >+ flowContext.recordNullityMismatch(scope, this.expression, nullStatus, methodBinding.returnType); >+ } >+ } > } > > /** >@@ -142,11 +190,11 @@ > } > } > if (this.saveValueVariable != null) { >- codeStream.addVariable(this.saveValueVariable); > codeStream.load(this.saveValueVariable); > } > if (this.expression != null && !alreadyGeneratedExpression) { > this.expression.generateCode(currentScope, codeStream, true); >+ // hook necessary for Code Snippet > generateStoreSaveValueIfNecessary(codeStream); > } > // output the suitable return bytecode or wrap the value inside a descriptor for doits >@@ -173,6 +221,8 @@ > public void generateStoreSaveValueIfNecessary(CodeStream codeStream){ > if (this.saveValueVariable != null) { > codeStream.store(this.saveValueVariable, false); >+ // the variable is visible as soon as the local is stored >+ codeStream.addVariable(this.saveValueVariable); > } > } > >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java >index a2cdd89..d625d5b 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java >@@ -352,9 +352,8 @@ > } > // 26903, need extra cast to store null in array local var > if (localBinding.type.isArrayType() >- && (assignment.expression.resolvedType == TypeBinding.NULL // arrayLoc = null >- || ((assignment.expression instanceof CastExpression) // arrayLoc = (type[])null >- && (((CastExpression)assignment.expression).innermostCastedExpression().resolvedType == TypeBinding.NULL)))){ >+ && ((assignment.expression instanceof CastExpression) // arrayLoc = (type[])null >+ && (((CastExpression)assignment.expression).innermostCastedExpression().resolvedType == TypeBinding.NULL))){ > codeStream.checkcast(localBinding.type); > } > >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java >index e1b10d9..e8ce295 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,7 +7,13 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >- * Stephan Herrmann - Contribution for bug 335093 - [compiler][null] minimal hook for future null annotation support >+ * Stephan Herrmann - Contributions for >+ * bug 335093 - [compiler][null] minimal hook for future null annotation support >+ * bug 349326 - [1.7] new warning for missing try-with-resources >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 365983 - [compiler][null] AIOOB with null annotation analysis and varargs >+ * bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK >+ * bug 370930 - NonNull annotation not considered for enhanced for loops > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >@@ -55,8 +61,57 @@ > public static final int COMPLAINED_FAKE_REACHABLE = 1; > public static final int COMPLAINED_UNREACHABLE = 2; > >-/** Empty hook for checking null status against declaration using null annotations, once this will be supported. */ >-protected int checkAgainstNullAnnotation(BlockScope currentScope, LocalVariableBinding local, int nullStatus) { >+ >+/** Analysing arguments of MessageSend, ExplicitConstructorCall, AllocationExpression. */ >+protected void analyseArguments(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, MethodBinding methodBinding, Expression[] arguments) >+{ >+ // compare actual null-status against parameter annotations of the called method: >+ if (arguments != null && methodBinding.parameterNonNullness != null) { >+ >+ // check if varargs need special treatment: >+ int numParamsToCheck = methodBinding.parameters.length; >+ boolean passThrough = false; >+ if (methodBinding.isVarargs()) { >+ int varArgPos = numParamsToCheck-1; >+ // this if-block essentially copied from generateArguments(..): >+ if (numParamsToCheck == arguments.length) { >+ TypeBinding varArgsType = methodBinding.parameters[varArgPos]; >+ TypeBinding lastType = arguments[varArgPos].resolvedType; >+ if (lastType == TypeBinding.NULL >+ || (varArgsType.dimensions() == lastType.dimensions() >+ && lastType.isCompatibleWith(varArgsType))) >+ passThrough = true; // pass directly as-is >+ } >+ if (!passThrough) >+ numParamsToCheck--; // with non-passthrough varargs last param is fed from individual args -> don't check >+ } >+ >+ for (int i = 0; i < numParamsToCheck; i++) { >+ if (methodBinding.parameterNonNullness[i] == Boolean.TRUE) { >+ TypeBinding expectedType = methodBinding.parameters[i]; >+ Expression argument = arguments[i]; >+ int nullStatus = argument.nullStatus(flowInfo); // slight loss of precision: should also use the null info from the receiver. >+ if (nullStatus != FlowInfo.NON_NULL) // if required non-null is not provided >+ flowContext.recordNullityMismatch(currentScope, argument, nullStatus, expectedType); >+ } >+ } >+ } >+} >+ >+/** Check null-ness of 'local' against a possible null annotation */ >+protected int checkAssignmentAgainstNullAnnotation(BlockScope currentScope, FlowContext flowContext, >+ LocalVariableBinding local, int nullStatus, Expression expression) >+{ >+ if (local != null) { >+ if ((local.tagBits & TagBits.AnnotationNonNull) != 0 >+ && nullStatus != FlowInfo.NON_NULL) { >+ flowContext.recordNullityMismatch(currentScope, expression, nullStatus, local.type); >+ return FlowInfo.NON_NULL; >+ } else if ((local.tagBits & TagBits.AnnotationNullable) != 0 >+ && nullStatus == FlowInfo.UNKNOWN) { // provided a legacy type? >+ return FlowInfo.POTENTIALLY_NULL; // -> use more specific info from the annotation >+ } >+ } > return nullStatus; > } > >@@ -70,18 +125,22 @@ > > // Report an error if necessary (if even more unreachable than previously reported > // complaintLevel = 0 if was reachable up until now, 1 if fake reachable (deadcode), 2 if fatal unreachable (error) >-public int complainIfUnreachable(FlowInfo flowInfo, BlockScope scope, int previousComplaintLevel) { >+public int complainIfUnreachable(FlowInfo flowInfo, BlockScope scope, int previousComplaintLevel, boolean endOfBlock) { > if ((flowInfo.reachMode() & FlowInfo.UNREACHABLE) != 0) { > if ((flowInfo.reachMode() & FlowInfo.UNREACHABLE_OR_DEAD) != 0) > this.bits &= ~ASTNode.IsReachable; > if (flowInfo == FlowInfo.DEAD_END) { > if (previousComplaintLevel < COMPLAINED_UNREACHABLE) { > scope.problemReporter().unreachableCode(this); >+ if (endOfBlock) >+ scope.checkUnclosedCloseables(flowInfo, null, null, null); > } > return COMPLAINED_UNREACHABLE; > } else { > if (previousComplaintLevel < COMPLAINED_FAKE_REACHABLE) { > scope.problemReporter().fakeReachable(this); >+ if (endOfBlock) >+ scope.checkUnclosedCloseables(flowInfo, null, null, null); > } > return COMPLAINED_FAKE_REACHABLE; > } >@@ -155,10 +214,11 @@ > if (scope.isBoxingCompatibleWith(expressionType, targetType)) > return true; > >- return expressionType.isBaseType() // narrowing then boxing ? >+ return expressionType.isBaseType() // narrowing then boxing ? Only allowed for some target types see 362279 > && !targetType.isBaseType() > && !targetType.isTypeVariable() > && scope.compilerOptions().sourceLevel >= org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_5 // autoboxing >+ && (targetType.id == TypeIds.T_JavaLangByte || targetType.id == TypeIds.T_JavaLangShort || targetType.id == TypeIds.T_JavaLangCharacter) > && expression.isConstantValueOfTypeAssignableToType(expressionType, scope.environment().computeBoxingType(targetType)); > } > >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java >index 5b171fc..03c6e80 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java >@@ -7,7 +7,9 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >- * Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE >+ * Stephan Herrmann - Contributions for >+ * bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE >+ * bug 349326 - [1.7] new warning for missing try-with-resources > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >@@ -99,7 +101,7 @@ > } else { > fallThroughState = FALLTHROUGH; // reset below if needed > } >- if ((complaintLevel = statement.complainIfUnreachable(caseInits, this.scope, complaintLevel)) < Statement.COMPLAINED_UNREACHABLE) { >+ if ((complaintLevel = statement.complainIfUnreachable(caseInits, this.scope, complaintLevel, true)) < Statement.COMPLAINED_UNREACHABLE) { > caseInits = statement.analyseCode(this.scope, switchContext, caseInits); > if (caseInits == FlowInfo.DEAD_END) { > fallThroughState = ESCAPING; >@@ -461,6 +463,9 @@ > break checkType; > } else if (expressionType.isEnum()) { > isEnumSwitch = true; >+ if (upperScope.compilerOptions().complianceLevel < ClassFileConstants.JDK1_5) { >+ upperScope.problemReporter().incorrectSwitchType(this.expression, expressionType); // https://bugs.eclipse.org/bugs/show_bug.cgi?id=360317 >+ } > break checkType; > } else if (upperScope.isBoxingCompatibleWith(expressionType, TypeBinding.INT)) { > this.expression.computeConversion(upperScope, TypeBinding.INT, expressionType); >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java >index 7e3d4c2..e7dc253 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,6 +7,9 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contributions for >+ * bug 359334 - Analysis for resource leak warnings does not consider exceptions as method exit points >+ * bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >@@ -35,6 +38,7 @@ > this.exception.checkNPE(currentScope, flowContext, flowInfo); > // need to check that exception thrown is actually caught somewhere > flowContext.checkExceptionHandlers(this.exceptionType, this, flowInfo, currentScope); >+ currentScope.checkUnclosedCloseables(flowInfo, flowContext, this, currentScope); > return FlowInfo.DEAD_END; > } > >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java >index 5fc3878..0534970 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,7 +7,12 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >- * Stephan Herrmann - Contribution for bug 332637 - Dead Code detection removing code that isn't dead >+ * Stephan Herrmann - Contributions for >+ * bug 332637 - Dead Code detection removing code that isn't dead >+ * bug 358827 - [1.7] exception analysis for t-w-r spoils null analysis >+ * bug 349326 - [1.7] new warning for missing try-with-resources >+ * bug 359334 - Analysis for resource leak warnings does not consider exceptions as method exit points >+ * bug 358903 - Filter practically unimportant resource leak warnings > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >@@ -65,6 +70,7 @@ > // for local variables table attributes > int mergedInitStateIndex = -1; > int preTryInitStateIndex = -1; >+ int postTryInitStateIndex = -1; > int[] postResourcesInitStateIndexes; > int naturalExitMergeInitStateIndex = -1; > int[] catchExitInitStateIndexes; >@@ -124,8 +130,14 @@ > for (int i = 0; i < resourcesLength; i++) { > flowInfo = this.resources[i].analyseCode(currentScope, handlingContext, flowInfo.copy()); > this.postResourcesInitStateIndexes[i] = currentScope.methodScope().recordInitializationStates(flowInfo); >- this.resources[i].binding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways. >- TypeBinding type = this.resources[i].binding.type; >+ LocalVariableBinding resourceBinding = this.resources[i].binding; >+ resourceBinding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways. >+ if (resourceBinding.closeTracker != null) { >+ // this was false alarm, we don't need to track the resource >+ this.tryBlock.scope.removeTrackingVar(resourceBinding.closeTracker); >+ // keep the tracking variable in the resourceBinding in order to prevent creating a new one while analyzing the try block >+ } >+ TypeBinding type = resourceBinding.type; > if (type != null && type.isValidBinding()) { > ReferenceBinding binding = (ReferenceBinding) type; > MethodBinding closeMethod = binding.getExactMethod(ConstantPool.Close, new TypeBinding [0], this.scope.compilationUnitScope()); // scope needs to be tighter >@@ -145,7 +157,9 @@ > if ((tryInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) > this.bits |= ASTNode.IsTryBlockExiting; > } >- >+ if (resourcesLength > 0) { >+ this.postTryInitStateIndex = currentScope.methodScope().recordInitializationStates(tryInfo); >+ } > // check unreachable catch blocks > handlingContext.complainIfUnusedExceptionHandlers(this.scope, this); > >@@ -229,6 +243,14 @@ > if (subInfo == FlowInfo.DEAD_END) { > this.bits |= ASTNode.IsSubRoutineEscaping; > this.scope.problemReporter().finallyMustCompleteNormally(this.finallyBlock); >+ } else { >+ // for resource analysis we need the finallyInfo in these nested scopes: >+ FlowInfo finallyInfo = subInfo.copy(); >+ this.tryBlock.scope.finallyInfo = finallyInfo; >+ if (this.catchBlocks != null) { >+ for (int i = 0; i < this.catchBlocks.length; i++) >+ this.catchBlocks[i].scope.finallyInfo = finallyInfo; >+ } > } > this.subRoutineInits = subInfo; > // process the try block in a context handling the local exceptions. >@@ -250,15 +272,21 @@ > for (int i = 0; i < resourcesLength; i++) { > flowInfo = this.resources[i].analyseCode(currentScope, handlingContext, flowInfo.copy()); > this.postResourcesInitStateIndexes[i] = currentScope.methodScope().recordInitializationStates(flowInfo); >- this.resources[i].binding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways. >- TypeBinding type = this.resources[i].binding.type; >+ LocalVariableBinding resourceBinding = this.resources[i].binding; >+ resourceBinding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways. >+ if (resourceBinding.closeTracker != null) { >+ // this was false alarm, we don't need to track the resource >+ this.tryBlock.scope.removeTrackingVar(resourceBinding.closeTracker); >+ // keep the tracking variable in the resourceBinding in order to prevent creating a new one while analyzing the try block >+ } >+ TypeBinding type = resourceBinding.type; > if (type != null && type.isValidBinding()) { > ReferenceBinding binding = (ReferenceBinding) type; > MethodBinding closeMethod = binding.getExactMethod(ConstantPool.Close, new TypeBinding [0], this.scope.compilationUnitScope()); // scope needs to be tighter > if (closeMethod != null && closeMethod.returnType.id == TypeIds.T_void) { > ReferenceBinding[] thrownExceptions = closeMethod.thrownExceptions; > for (int j = 0, length = thrownExceptions.length; j < length; j++) { >- handlingContext.checkExceptionHandlers(thrownExceptions[j], this.resources[j], flowInfo, currentScope); >+ handlingContext.checkExceptionHandlers(thrownExceptions[j], this.resources[i], flowInfo, currentScope, true); > } > } > } >@@ -271,7 +299,9 @@ > if ((tryInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) > this.bits |= ASTNode.IsTryBlockExiting; > } >- >+ if (resourcesLength > 0) { >+ this.postTryInitStateIndex = currentScope.methodScope().recordInitializationStates(tryInfo); >+ } > // check unreachable catch blocks > handlingContext.complainIfUnusedExceptionHandlers(this.scope, this); > >@@ -490,6 +520,13 @@ > // inline resource closure > if (i > 0) { > int invokeCloseStartPc = codeStream.position; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=343785 >+ if (this.postTryInitStateIndex != -1) { >+ /* https://bugs.eclipse.org/bugs/show_bug.cgi?id=361053, we are just past a synthetic instance of try-catch-finally. >+ Our initialization type state is the same as it was at the end of the just concluded try (catch rethrows) >+ */ >+ codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.postTryInitStateIndex); >+ codeStream.addDefinitelyAssignedVariables(currentScope, this.postTryInitStateIndex); >+ } > codeStream.load(localVariable); > codeStream.ifnull(exitLabel); > codeStream.load(localVariable); >@@ -876,9 +913,6 @@ > if (finallyMode == FINALLY_INLINE) { > if (isStackMapFrameCodeStream) { > ((StackMapFrameCodeStream) codeStream).pushStateIndex(stateIndex); >- } >- if (secretLocal != null) { >- codeStream.addVariable(secretLocal); > } > // cannot use jsr bytecode, then simply inline the subroutine > // inside try block, ensure to deactivate all catch block exception handlers while inlining finally block >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java >index b475932..a694c1a 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contribution for Bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop) > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >@@ -493,6 +494,13 @@ > return null; > } > >+public CompilationUnitDeclaration getCompilationUnitDeclaration() { >+ if (this.scope != null) { >+ return this.scope.compilationUnitScope().referenceContext; >+ } >+ return null; >+} >+ > /** > * Generic bytecode generation for type > */ >@@ -625,7 +633,11 @@ > this.scope.problemReporter().unusedPrivateType(this); > } > } >- InitializationFlowContext initializerContext = new InitializationFlowContext(null, this, flowInfo, flowContext, this.initializerScope); >+ // for local classes we use the flowContext as our parent, but never use an initialization context for this purpose >+ // see Bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop) >+ FlowContext parentContext = (flowContext instanceof InitializationFlowContext) ? null : flowContext; >+ InitializationFlowContext initializerContext = new InitializationFlowContext(parentContext, this, flowInfo, flowContext, this.initializerScope); >+ // no static initializer in local classes, thus no need to set parent: > InitializationFlowContext staticInitializerContext = new InitializationFlowContext(null, this, flowInfo, flowContext, this.staticInitializerScope); > FlowInfo nonStaticFieldInfo = flowInfo.unconditionalFieldLessCopy(); > FlowInfo staticFieldInfo = flowInfo.unconditionalFieldLessCopy(); >@@ -684,8 +696,9 @@ > if (method.ignoreFurtherInvestigation) > continue; > if (method.isInitializationMethod()) { >+ // pass down the appropriate initializerContext: > if (method.isStatic()) { // <clinit> >- method.analyseCode( >+ ((Clinit)method).analyseCode( > this.scope, > staticInitializerContext, > staticFieldInfo.unconditionalInits().discardNonFieldInitializations().addInitializationsFrom(outerInfo)); >@@ -693,7 +706,8 @@ > ((ConstructorDeclaration)method).analyseCode(this.scope, initializerContext, constructorInfo.copy(), flowInfo.reachMode()); > } > } else { // regular method >- method.analyseCode(this.scope, null, flowInfo.copy()); >+ // pass down the parentContext (NOT an initializer context, see above): >+ ((MethodDeclaration)method).analyseCode(this.scope, parentContext, flowInfo.copy()); > } > } > } >@@ -1354,9 +1368,9 @@ > if (this.fields != null) { > int length = this.fields.length; > for (int i = 0; i < length; i++) { >- FieldDeclaration field; >- if ((field = this.fields[i]).isStatic()) { >- // local type cannot have static fields >+ FieldDeclaration field = this.fields[i]; >+ if (field.isStatic() && !field.isFinal()) { >+ // local type cannot have static fields that are not final, https://bugs.eclipse.org/bugs/show_bug.cgi?id=244544 > } else { > field.traverse(visitor, this.initializerScope); > } >@@ -1457,4 +1471,5 @@ > public boolean isSecondary() { > return (this.bits & ASTNode.IsSecondaryType) != 0; > } >+ > } >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java >index c51042e..e35ea9c 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java >@@ -7,7 +7,9 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >- * Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE >+ * Stephan Herrmann - Contributions for >+ * bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE >+ * bug 349326 - [1.7] new warning for missing try-with-resources > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >@@ -113,7 +115,7 @@ > currentScope.methodScope().recordInitializationStates( > condInfo.initsWhenTrue()); > >- if (this.action.complainIfUnreachable(actionInfo, currentScope, initialComplaintLevel) < Statement.COMPLAINED_UNREACHABLE) { >+ if (this.action.complainIfUnreachable(actionInfo, currentScope, initialComplaintLevel, true) < Statement.COMPLAINED_UNREACHABLE) { > actionInfo = this.action.analyseCode(currentScope, loopingContext, actionInfo); > } > >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/AnnotationInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/AnnotationInfo.java >index 3357d7d..d81ec1c 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/AnnotationInfo.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/AnnotationInfo.java >@@ -303,10 +303,6 @@ > currentOffset += 2; > return readTargetValue(currentOffset); > } >- if (CharOperation.equals(typeName, ConstantPool.JAVAX_ANNOTATION_PREDESTROY)) { >- this.standardAnnotationTagBits |= TagBits.AnnotationPreDestroy; >- return currentOffset; >- } > break; > case 32: > if (CharOperation.equals(typeName, ConstantPool.JAVA_LANG_ANNOTATION_RETENTION)) { >@@ -315,10 +311,6 @@ > } > if (CharOperation.equals(typeName, ConstantPool.JAVA_LANG_ANNOTATION_INHERITED)) { > this.standardAnnotationTagBits |= TagBits.AnnotationInherited; >- return currentOffset; >- } >- if (CharOperation.equals(typeName, ConstantPool.JAVAX_ANNOTATION_POSTCONSTRUCT)) { >- this.standardAnnotationTagBits |= TagBits.AnnotationPostConstruct; > return currentOffset; > } > break; >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.java >index 7095af1..a21b681 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2008 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -58,6 +58,9 @@ > int MethodRefTag = 10; > int InterfaceMethodRefTag = 11; > int NameAndTypeTag = 12; >+ int MethodHandleTag = 15; >+ int MethodTypeTag = 16; >+ int InvokeDynamicTag = 18; > > int ConstantMethodRefFixedSize = 5; > int ConstantClassFixedSize = 3; >@@ -70,6 +73,9 @@ > int ConstantStringFixedSize = 3; > int ConstantUtf8FixedSize = 3; > int ConstantNameAndTypeFixedSize = 5; >+ int ConstantMethodHandleFixedSize = 4; >+ int ConstantMethodTypeFixedSize = 3; >+ int ConstantInvokeDynamicFixedSize = 5; > > int MAJOR_VERSION_1_1 = 45; > int MAJOR_VERSION_1_2 = 46; >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java >index d2a2b62..fa2fb0f 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contribution for bug 365992 - [builder] [null] Change of nullness for a parameter doesn't trigger a build for the files that call the method > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.classfmt; > >@@ -207,6 +208,19 @@ > case ClassFileConstants.NameAndTypeTag : > this.constantPoolOffsets[i] = readOffset; > readOffset += ClassFileConstants.ConstantNameAndTypeFixedSize; >+ break; >+ case ClassFileConstants.MethodHandleTag : >+ this.constantPoolOffsets[i] = readOffset; >+ readOffset += ClassFileConstants.ConstantMethodHandleFixedSize; >+ break; >+ case ClassFileConstants.MethodTypeTag : >+ this.constantPoolOffsets[i] = readOffset; >+ readOffset += ClassFileConstants.ConstantMethodTypeFixedSize; >+ break; >+ case ClassFileConstants.InvokeDynamicTag : >+ this.constantPoolOffsets[i] = readOffset; >+ readOffset += ClassFileConstants.ConstantInvokeDynamicFixedSize; >+ break; > } > } > // Read and validate access flags >@@ -1057,6 +1071,16 @@ > return true; > if (hasStructuralAnnotationChanges(currentMethodInfo.getAnnotations(), otherMethodInfo.getAnnotations())) > return true; >+ // parameter annotations: >+ int currentAnnotatedParamsCount = currentMethodInfo.getAnnotatedParametersCount(); >+ int otherAnnotatedParamsCount = otherMethodInfo.getAnnotatedParametersCount(); >+ if (currentAnnotatedParamsCount != otherAnnotatedParamsCount) >+ return true; >+ for (int i=0; i<currentAnnotatedParamsCount; i++) { >+ if (hasStructuralAnnotationChanges(currentMethodInfo.getParameterAnnotations(i), otherMethodInfo.getParameterAnnotations(i))) >+ return true; >+ } >+ > if (!CharOperation.equals(currentMethodInfo.getSelector(), otherMethodInfo.getSelector())) > return true; > if (!CharOperation.equals(currentMethodInfo.getMethodDescriptor(), otherMethodInfo.getMethodDescriptor())) >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfo.java >index 26da081..88d60ac 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfo.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfo.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contribution for bug 186342 - [compiler][null] Using annotations for null checking > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.classfmt; > >@@ -270,6 +271,9 @@ > public IBinaryAnnotation[] getParameterAnnotations(int index) { > return null; > } >+public int getAnnotatedParametersCount() { >+ return 0; >+} > /** > * Answer the name of the method. > * >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfoWithParameterAnnotations.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfoWithParameterAnnotations.java >index 9d871b1..8f31b3e 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfoWithParameterAnnotations.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfoWithParameterAnnotations.java >@@ -8,6 +8,7 @@ > * Contributors: > * tyeung@bea.com - initial API and implementation > * IBM Corporation - fix for bug 342757 >+ * Stephan Herrmann - Contribution for bug 186342 - [compiler][null] Using annotations for null checking > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.classfmt; > >@@ -36,6 +37,9 @@ > public IBinaryAnnotation[] getParameterAnnotations(int index) { > return this.parameterAnnotations[index]; > } >+public int getAnnotatedParametersCount() { >+ return this.parameterAnnotations == null ? 0 : this.parameterAnnotations.length; >+} > protected void initialize() { > for (int i = 0, l = this.parameterAnnotations == null ? 0 : this.parameterAnnotations.length; i < l; i++) { > AnnotationInfo[] infos = this.parameterAnnotations[i]; >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java >index c875c9b..c449385 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -248,8 +248,6 @@ > public static final char[] JAVA_LANG_SAFEVARARGS = "Ljava/lang/SafeVarargs;".toCharArray(); //$NON-NLS-1$ > // java 7 java.lang.invoke.MethodHandle.invokeExact(..)/invokeGeneric(..) > public static final char[] JAVA_LANG_INVOKE_METHODHANDLE_POLYMORPHICSIGNATURE = "Ljava/lang/invoke/MethodHandle$PolymorphicSignature;".toCharArray(); //$NON-NLS-1$ >- public static final char[] JAVAX_ANNOTATION_POSTCONSTRUCT = "Ljavax/annotation/PostConstruct;".toCharArray(); //$NON-NLS-1$ >- public static final char[] JAVAX_ANNOTATION_PREDESTROY = "Ljavax/annotation/PreDestroy;".toCharArray(); //$NON-NLS-1$ > > public static final char[] HashCode = "hashCode".toCharArray(); //$NON-NLS-1$ > public static final char[] HashCodeSignature = "()I".toCharArray(); //$NON-NLS-1$; >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java >index 14b8845..e61cde3 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java >@@ -248,8 +248,17 @@ > this.stackDepthMarkers.add(new StackDepthMarker(pc, delta, typeBinding)); > } else { > int size = this.stackDepthMarkers.size(); >- if (size == 0 || ((StackDepthMarker) this.stackDepthMarkers.get(size - 1)).pc != this.position) { >+ if (size == 0) { > this.stackDepthMarkers.add(new StackDepthMarker(pc, delta, typeBinding)); >+ } else { >+ StackDepthMarker stackDepthMarker = (StackDepthMarker) this.stackDepthMarkers.get(size - 1); >+ if (stackDepthMarker.pc != this.position) { >+ this.stackDepthMarkers.add(new StackDepthMarker(pc, delta, typeBinding)); >+ } else { >+ // We replace the recorded stack depth marker with a new value that contains the given typeBinding >+ // This case can happen when multiple conditional expression are nested see bug 362591 >+ this.stackDepthMarkers.set(size - 1, new StackDepthMarker(pc, delta, typeBinding)); >+ } > } > } > } >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryMethod.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryMethod.java >index d75686b..177ae24 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryMethod.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryMethod.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contribution for bug 186342 - [compiler][null] Using annotations for null checking > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.env; > >@@ -66,6 +67,13 @@ > IBinaryAnnotation[] getParameterAnnotations(int index); > > /** >+ * Answer the number of parameter annotations that can be retrieved >+ * using {@link #getParameterAnnotations(int)}. >+ * @return one beyond the highest legal argument to {@link #getParameterAnnotations(int)}. >+ */ >+int getAnnotatedParametersCount(); >+ >+/** > * Answer the name of the method. > * > * For a constructor, answer <init> & <clinit> for a clinit method. >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ICompilationUnit.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ICompilationUnit.java >index adbcaa6..bbe34a2 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ICompilationUnit.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ICompilationUnit.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -35,4 +35,9 @@ > * For example, {java, lang}. > */ > char[][] getPackageName(); >+/** >+* Answer if optional problems should be ignored for this compilation unit. >+* Implementors should return <code>false</code> if there is no preference. >+*/ >+boolean ignoreOptionalProblems(); > } >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java >index c137b42..5cb4166 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java >@@ -252,4 +252,9 @@ > return (this.initsWhenTrue.isMarkedAsNullOrNonNullInAssertExpression(local) > || this.initsWhenFalse.isMarkedAsNullOrNonNullInAssertExpression(local)); > } >+ >+public void resetAssignmentInfo(LocalVariableBinding local) { >+ this.initsWhenTrue.resetAssignmentInfo(local); >+ this.initsWhenFalse.resetAssignmentInfo(local); >+} > } >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java >index 0590583..76784ee 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,6 +7,10 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contributions for >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 365519 - editorial cleanup after bug 186342 and bug 365387 >+ * bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.flow; > >@@ -17,6 +21,7 @@ > import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; > import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding; > import org.eclipse.jdt.internal.compiler.lookup.Scope; >+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; > import org.eclipse.jdt.internal.compiler.lookup.TypeIds; > import org.eclipse.jdt.internal.compiler.lookup.VariableBinding; > >@@ -30,10 +35,13 @@ > VariableBinding[] finalVariables; > int assignCount; > >+ // the following three arrays are in sync regarding their indices: > LocalVariableBinding[] nullLocals; >- Expression[] nullReferences; >+ ASTNode[] nullReferences; // Expressions for null checking, Statements for resource analysis >+ // cast to Expression is safe if corresponding nullCheckType != EXIT_RESOURCE > int[] nullCheckTypes; > int nullCount; >+ // see also the related field FlowContext#expectedTypes > > public FinallyFlowContext(FlowContext parent, ASTNode associatedNode) { > super(parent, associatedNode); >@@ -60,7 +68,7 @@ > } > } else { > // final local variable >- if (flowInfo.isPotentiallyAssigned((LocalVariableBinding) variable)) { >+ if (flowInfo.isPotentiallyAssigned((LocalVariableBinding)variable)) { > complained = true; > scope.problemReporter().duplicateInitializationOfFinalLocal( > (LocalVariableBinding) variable, >@@ -70,12 +78,12 @@ > // any reference reported at this level is removed from the parent context > // where it could also be reported again > if (complained) { >- FlowContext currentContext = this.parent; >+ FlowContext currentContext = this.getLocalParent(); > while (currentContext != null) { > //if (currentContext.isSubRoutine()) { > currentContext.removeFinalAssignmentIfAny(this.finalAssignments[i]); > //} >- currentContext = currentContext.parent; >+ currentContext = currentContext.getLocalParent(); > } > } > } >@@ -83,13 +91,18 @@ > // check inconsistent null checks > if ((this.tagBits & FlowContext.DEFER_NULL_DIAGNOSTIC) != 0) { // within an enclosing loop, be conservative > for (int i = 0; i < this.nullCount; i++) { >- this.parent.recordUsingNullReference(scope, this.nullLocals[i], >- this.nullReferences[i], this.nullCheckTypes[i], flowInfo); >+ if (this.nullCheckTypes[i] == ASSIGN_TO_NONNULL) >+ this.parent.recordNullityMismatch(scope, (Expression)this.nullReferences[i], >+ flowInfo.nullStatus(this.nullLocals[i]), this.expectedTypes[i]); >+ else >+ this.parent.recordUsingNullReference(scope, this.nullLocals[i], >+ this.nullReferences[i], this.nullCheckTypes[i], flowInfo); >+ > } > } > else { // no enclosing loop, be as precise as possible right now > for (int i = 0; i < this.nullCount; i++) { >- Expression expression = this.nullReferences[i]; >+ ASTNode location = this.nullReferences[i]; > // final local variable > LocalVariableBinding local = this.nullLocals[i]; > switch (this.nullCheckTypes[i]) { >@@ -98,11 +111,11 @@ > if (flowInfo.isDefinitelyNonNull(local)) { > if (this.nullCheckTypes[i] == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) { > if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { >- scope.problemReporter().localVariableRedundantCheckOnNonNull(local, expression); >+ scope.problemReporter().localVariableRedundantCheckOnNonNull(local, location); > } > } else { > if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { >- scope.problemReporter().localVariableNonNullComparedToNull(local, expression); >+ scope.problemReporter().localVariableNonNullComparedToNull(local, location); > } > } > continue; >@@ -112,6 +125,7 @@ > case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL: > case CAN_ONLY_NULL | IN_ASSIGNMENT: > case CAN_ONLY_NULL | IN_INSTANCEOF: >+ Expression expression = (Expression) location; > if (flowInfo.isDefinitelyNull(local)) { > switch(this.nullCheckTypes[i] & CONTEXT_MASK) { > case FlowContext.IN_COMPARISON_NULL: >@@ -160,11 +174,18 @@ > break; > case MAY_NULL: > if (flowInfo.isDefinitelyNull(local)) { >- scope.problemReporter().localVariableNullReference(local, expression); >+ scope.problemReporter().localVariableNullReference(local, location); > continue; > } > if (flowInfo.isPotentiallyNull(local)) { >- scope.problemReporter().localVariablePotentialNullReference(local, expression); >+ scope.problemReporter().localVariablePotentialNullReference(local, location); >+ } >+ break; >+ case ASSIGN_TO_NONNULL: >+ int nullStatus = flowInfo.nullStatus(local); >+ if (nullStatus != FlowInfo.NON_NULL) { >+ char[][] annotationName = scope.environment().getNonNullAnnotationName(); >+ scope.problemReporter().nullityMismatch((Expression) location, this.expectedTypes[i], nullStatus, annotationName); > } > break; > default: >@@ -213,7 +234,7 @@ > } > > public void recordUsingNullReference(Scope scope, LocalVariableBinding local, >- Expression reference, int checkType, FlowInfo flowInfo) { >+ ASTNode location, int checkType, FlowInfo flowInfo) { > if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0 && !flowInfo.isDefinitelyUnknown(local)) { > if ((this.tagBits & FlowContext.DEFER_NULL_DIAGNOSTIC) != 0) { // within an enclosing loop, be conservative > switch (checkType) { >@@ -223,6 +244,7 @@ > case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL: > case CAN_ONLY_NULL | IN_ASSIGNMENT: > case CAN_ONLY_NULL | IN_INSTANCEOF: >+ Expression reference = (Expression) location; > if (flowInfo.cannotBeNull(local)) { > if (checkType == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) { > if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { >@@ -296,7 +318,7 @@ > return; > } > if (flowInfo.canOnlyBeNull(local)) { >- scope.problemReporter().localVariableNullReference(local, reference); >+ scope.problemReporter().localVariableNullReference(local, location); > return; > } > break; >@@ -311,14 +333,14 @@ > if (flowInfo.isDefinitelyNonNull(local)) { > if (checkType == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) { > if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { >- scope.problemReporter().localVariableRedundantCheckOnNonNull(local, reference); >+ scope.problemReporter().localVariableRedundantCheckOnNonNull(local, location); > } > if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) { > flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS); > } > } else { > if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { >- scope.problemReporter().localVariableNonNullComparedToNull(local, reference); >+ scope.problemReporter().localVariableNonNullComparedToNull(local, location); > } > if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) { > flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS); >@@ -331,6 +353,7 @@ > case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL: > case CAN_ONLY_NULL | IN_ASSIGNMENT: > case CAN_ONLY_NULL | IN_INSTANCEOF: >+ Expression reference = (Expression) location; > if (flowInfo.isDefinitelyNull(local)) { > switch(checkType & CONTEXT_MASK) { > case FlowContext.IN_COMPARISON_NULL: >@@ -383,11 +406,11 @@ > break; > case MAY_NULL : > if (flowInfo.isDefinitelyNull(local)) { >- scope.problemReporter().localVariableNullReference(local, reference); >+ scope.problemReporter().localVariableNullReference(local, location); > return; > } > if (flowInfo.isPotentiallyNull(local)) { >- scope.problemReporter().localVariablePotentialNullReference(local, reference); >+ scope.problemReporter().localVariablePotentialNullReference(local, location); > return; > } > if (flowInfo.isDefinitelyNonNull(local)) { >@@ -403,7 +426,7 @@ > if(((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) || checkType == MAY_NULL > || (checkType & CONTEXT_MASK) == FlowContext.IN_ASSIGNMENT > || (checkType & CONTEXT_MASK) == FlowContext.IN_INSTANCEOF) { >- recordNullReference(local, reference, checkType); >+ recordNullReference(local, location, checkType); > } > // prepare to re-check with try/catch flow info > } >@@ -420,7 +443,7 @@ > } > > protected void recordNullReference(LocalVariableBinding local, >- Expression expression, int status) { >+ ASTNode expression, int status) { > if (this.nullCount == 0) { > this.nullLocals = new LocalVariableBinding[5]; > this.nullReferences = new Expression[5]; >@@ -442,4 +465,14 @@ > this.nullReferences[this.nullCount] = expression; > this.nullCheckTypes[this.nullCount++] = status; > } >+protected boolean internalRecordNullityMismatch(Expression expression, int nullStatus, TypeBinding expectedType, int checkType) { >+ // cf. decision structure inside FinallyFlowContext.recordUsingNullReference(..) >+ if (nullStatus == FlowInfo.UNKNOWN || >+ ((this.tagBits & FlowContext.DEFER_NULL_DIAGNOSTIC) != 0 && nullStatus != FlowInfo.NULL)) { >+ recordExpectedType(expectedType, this.nullCount); >+ recordNullReference(expression.localVariableBinding(), expression, checkType); >+ return true; >+ } >+ return false; >+} > } >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java >index e768ff0..489bb1d 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java >@@ -1,20 +1,26 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contributions for >+ * bug 358827 - [1.7] exception analysis for t-w-r spoils null analysis >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.flow; > > import java.util.ArrayList; >+ > import org.eclipse.jdt.core.compiler.CharOperation; >-import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; > import org.eclipse.jdt.internal.compiler.ast.ASTNode; >+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; > import org.eclipse.jdt.internal.compiler.ast.Expression; >+import org.eclipse.jdt.internal.compiler.ast.FakedTrackingVariable; > import org.eclipse.jdt.internal.compiler.ast.LabeledStatement; > import org.eclipse.jdt.internal.compiler.ast.Reference; > import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; >@@ -50,6 +56,10 @@ > // any null related operation happening within the try block > > public int tagBits; >+ >+ // array to store the expected type from the potential error location (for display in error messages): >+ public TypeBinding[] expectedTypes = null; >+ > public static final int DEFER_NULL_DIAGNOSTIC = 0x1; > public static final int PREEMPT_NULL_DIAGNOSTIC = 0x2; > /** >@@ -64,6 +74,10 @@ > public static final int CAN_ONLY_NON_NULL = 0x0002; > //check against non null, with definite values -- comparisons > public static final int MAY_NULL = 0x0003; >+//check binding a value to a @NonNull variable >+public final static int ASSIGN_TO_NONNULL = 0x0080; >+//check against unclosed resource at early exit: >+public static final int EXIT_RESOURCE = 0x0800; > // check against null, with potential values -- NPE guard > public static final int CHECK_MASK = 0x00FF; > public static final int IN_COMPARISON_NULL = 0x0100; >@@ -197,14 +211,16 @@ > > traversedContext.recordReturnFrom(flowInfo.unconditionalInits()); > >- if (traversedContext instanceof InsideSubRoutineFlowContext) { >- ASTNode node = traversedContext.associatedNode; >- if (node instanceof TryStatement) { >- TryStatement tryStatement = (TryStatement) node; >- flowInfo.addInitializationsFrom(tryStatement.subRoutineInits); // collect inits >+ if (!isExceptionOnAutoClose) { >+ if (traversedContext instanceof InsideSubRoutineFlowContext) { >+ ASTNode node = traversedContext.associatedNode; >+ if (node instanceof TryStatement) { >+ TryStatement tryStatement = (TryStatement) node; >+ flowInfo.addInitializationsFrom(tryStatement.subRoutineInits); // collect inits >+ } > } > } >- traversedContext = traversedContext.parent; >+ traversedContext = traversedContext.getLocalParent(); > } > // if reaches this point, then there are some remaining unhandled exception types. > if (isExceptionOnAutoClose) { >@@ -350,7 +366,7 @@ > flowInfo.addInitializationsFrom(tryStatement.subRoutineInits); // collect inits > } > } >- traversedContext = traversedContext.parent; >+ traversedContext = traversedContext.getLocalParent(); > } > // if reaches this point, then there are some remaining unhandled exception types. > nextReport: for (int i = 0; i < raisedCount; i++) { >@@ -382,9 +398,9 @@ > current = initializationContext.initializationParent; > } else if (current instanceof ExceptionHandlingFlowContext) { > ExceptionHandlingFlowContext exceptionContext = (ExceptionHandlingFlowContext) current; >- current = exceptionContext.initializationParent == null ? exceptionContext.parent : exceptionContext.initializationParent; >+ current = exceptionContext.initializationParent == null ? exceptionContext.getLocalParent() : exceptionContext.initializationParent; > } else { >- current = current.parent; >+ current = current.getLocalParent(); > } > } while (current != null); > // not found >@@ -408,7 +424,7 @@ > return current; > return lastNonReturningSubRoutine; > } >- current = current.parent; >+ current = current.getLocalParent(); > } > // not found > return null; >@@ -445,7 +461,7 @@ > // label is found, but not a continuable location > return FlowContext.NotContinuableContext; > } >- current = current.parent; >+ current = current.getLocalParent(); > } > // not found > return null; >@@ -464,7 +480,7 @@ > if (lastNonReturningSubRoutine == null) return current; > return lastNonReturningSubRoutine; > } >- current = current.parent; >+ current = current.getLocalParent(); > } > // not found > return null; >@@ -484,10 +500,20 @@ > return current; > return lastNonReturningSubRoutine; > } >- current = current.parent; >+ current = current.getLocalParent(); > } > // not found > return null; >+} >+ >+/** >+ * Answer the parent flow context but be careful not to cross the boundary of a nested type, >+ * or null if no such parent exists. >+ */ >+public FlowContext getLocalParent() { >+ if (this.associatedNode instanceof AbstractMethodDeclaration || this.associatedNode instanceof TypeDeclaration) >+ return null; >+ return this.parent; > } > > public String individualToString() { >@@ -534,6 +560,34 @@ > // default implementation: do nothing > } > >+/** >+ * Record that we found an early exit from a method while a resource is in scope. >+ * @param scope enclosing scope >+ * @param flowInfo flowInfo at the point of the early exit >+ * @param trackingVar representation of the resource >+ * @param reference the return or throw statement marking the early exit >+ * @return true if the situation has been handled by this flow context. >+ */ >+public boolean recordExitAgainstResource(BlockScope scope, FlowInfo flowInfo, FakedTrackingVariable trackingVar, ASTNode reference) { >+ return false; // not handled >+} >+ >+protected void recordExpectedType(TypeBinding expectedType, int nullCount) { >+ if (nullCount == 0) { >+ this.expectedTypes = new TypeBinding[5]; >+ } else if (this.expectedTypes == null) { >+ int size = 5; >+ while (size <= nullCount) size *= 2; >+ this.expectedTypes = new TypeBinding[size]; >+ } >+ else if (nullCount >= this.expectedTypes.length) { >+ int oldLen = this.expectedTypes.length; >+ System.arraycopy(this.expectedTypes, 0, >+ this.expectedTypes = new TypeBinding[nullCount * 2], 0, oldLen); >+ } >+ this.expectedTypes[nullCount] = expectedType; >+} >+ > protected boolean recordFinalAssignment(VariableBinding variable, Reference finalReference) { > return true; // keep going > } >@@ -542,7 +596,9 @@ > * Record a null reference for use by deferred checks. Only looping or > * finally contexts really record that information. > * @param local the local variable involved in the check >- * @param expression the expression within which local lays >+ * @param location the location triggering the analysis, for normal null dereference >+ * this is an expression resolving to 'local', for resource leaks it is an >+ * early exit statement. > * @param status the status against which the check must be performed; one of > * {@link #CAN_ONLY_NULL CAN_ONLY_NULL}, {@link #CAN_ONLY_NULL_NON_NULL > * CAN_ONLY_NULL_NON_NULL}, {@link #MAY_NULL MAY_NULL}, >@@ -551,7 +607,7 @@ > * {@link #IN_COMPARISON_NON_NULL}, {@link #IN_ASSIGNMENT} or {@link #IN_INSTANCEOF}) > */ > protected void recordNullReference(LocalVariableBinding local, >- Expression expression, int status) { >+ ASTNode location, int status) { > // default implementation: do nothing > } > >@@ -567,7 +623,7 @@ > if (!context.recordFinalAssignment(variable, finalReference)) { > break; // no need to keep going > } >- context = context.parent; >+ context = context.getLocalParent(); > } > } > } >@@ -582,7 +638,9 @@ > * context). > * @param scope the scope into which the check is performed > * @param local the local variable involved in the check >- * @param reference the expression within which local lies >+ * @param location the location triggering the analysis, for normal null dereference >+ * this is an expression resolving to 'local', for resource leaks it is an >+ * early exit statement. > * @param checkType the status against which the check must be performed; one > * of {@link #CAN_ONLY_NULL CAN_ONLY_NULL}, {@link #CAN_ONLY_NULL_NON_NULL > * CAN_ONLY_NULL_NON_NULL}, {@link #MAY_NULL MAY_NULL}, potentially >@@ -594,7 +652,7 @@ > * code that follows the current point) > */ > public void recordUsingNullReference(Scope scope, LocalVariableBinding local, >- Expression reference, int checkType, FlowInfo flowInfo) { >+ ASTNode location, int checkType, FlowInfo flowInfo) { > if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0 || > flowInfo.isDefinitelyUnknown(local)) { > return; >@@ -605,14 +663,14 @@ > if (flowInfo.isDefinitelyNonNull(local)) { > if (checkType == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) { > if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { >- scope.problemReporter().localVariableRedundantCheckOnNonNull(local, reference); >+ scope.problemReporter().localVariableRedundantCheckOnNonNull(local, location); > } > if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) { > flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS); > } > } else { > if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { >- scope.problemReporter().localVariableNonNullComparedToNull(local, reference); >+ scope.problemReporter().localVariableNonNullComparedToNull(local, location); > } > if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) { > flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS); >@@ -628,6 +686,7 @@ > case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL: > case CAN_ONLY_NULL | IN_ASSIGNMENT: > case CAN_ONLY_NULL | IN_INSTANCEOF: >+ Expression reference = (Expression)location; > if (flowInfo.isDefinitelyNull(local)) { > switch(checkType & CONTEXT_MASK) { > case FlowContext.IN_COMPARISON_NULL: >@@ -682,11 +741,11 @@ > break; > case MAY_NULL : > if (flowInfo.isDefinitelyNull(local)) { >- scope.problemReporter().localVariableNullReference(local, reference); >+ scope.problemReporter().localVariableNullReference(local, location); > return; > } > if (flowInfo.isPotentiallyNull(local)) { >- scope.problemReporter().localVariablePotentialNullReference(local, reference); >+ scope.problemReporter().localVariablePotentialNullReference(local, location); > return; > } > break; >@@ -694,7 +753,7 @@ > // never happens > } > if (this.parent != null) { >- this.parent.recordUsingNullReference(scope, local, reference, checkType, >+ this.parent.recordUsingNullReference(scope, local, location, checkType, > flowInfo); > } > } >@@ -732,4 +791,31 @@ > buffer.append(individualToString()).append('\n'); > return buffer.toString(); > } >+ >+/** >+ * Record that a nullity mismatch was detected against an annotated type reference. >+ * @param currentScope scope for error reporting >+ * @param expression the expression violating the specification >+ * @param nullStatus the null status of expression at the current location >+ * @param expectedType the declared type of the spec'ed variable, for error reporting. >+ */ >+public void recordNullityMismatch(BlockScope currentScope, Expression expression, int nullStatus, TypeBinding expectedType) { >+ if (expression.localVariableBinding() != null) { // flowContext cannot yet handle non-localvar expressions (e.g., fields) >+ // find the inner-most flowContext that might need deferred handling: >+ FlowContext currentContext = this; >+ while (currentContext != null) { >+ // some flow contexts implement deferred checking, should we participate in that? >+ if (currentContext.internalRecordNullityMismatch(expression, nullStatus, expectedType, ASSIGN_TO_NONNULL)) >+ return; >+ currentContext = currentContext.parent; >+ } >+ } >+ // no reason to defer, so report now: >+ char[][] annotationName = currentScope.environment().getNonNullAnnotationName(); >+ currentScope.problemReporter().nullityMismatch(expression, expectedType, nullStatus, annotationName); >+} >+protected boolean internalRecordNullityMismatch(Expression expression, int nullStatus, TypeBinding expectedType, int checkType) { >+ // nop, to be overridden in subclasses >+ return false; // not recorded >+} > } >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java >index 5c995f9..b931372 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java >@@ -405,12 +405,28 @@ > public static UnconditionalFlowInfo mergedOptimizedBranchesIfElse( > FlowInfo initsWhenTrue, boolean isOptimizedTrue, > FlowInfo initsWhenFalse, boolean isOptimizedFalse, >- boolean allowFakeDeadBranch, FlowInfo flowInfo, IfStatement ifStatement) { >+ boolean allowFakeDeadBranch, FlowInfo flowInfo, IfStatement ifStatement, >+ boolean reportDeadCodeInKnownPattern) { > UnconditionalFlowInfo mergedInfo; > if (isOptimizedTrue){ > if (initsWhenTrue == FlowInfo.DEAD_END && allowFakeDeadBranch) { >- mergedInfo = initsWhenFalse.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD). >- unconditionalInits(); >+ if (!reportDeadCodeInKnownPattern) { >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=256796 >+ // do not report code even after if-else as dead as a consequence of analysis done in known dead code pattern >+ // when the CompilerOptions$reportDeadCodeInTrivialIfStatement option is disabled >+ if (ifStatement.elseStatement == null) { >+ mergedInfo = flowInfo.unconditionalInits(); >+ } else { >+ mergedInfo = initsWhenFalse.unconditionalInits(); >+ if (initsWhenFalse != FlowInfo.DEAD_END) { >+ // let the definitely true status of known dead code pattern not affect the reachability >+ mergedInfo.setReachMode(flowInfo.reachMode()); >+ } >+ } >+ } else { >+ mergedInfo = initsWhenFalse.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD). >+ unconditionalInits(); >+ } > } > else { > mergedInfo = >@@ -421,8 +437,23 @@ > } > else if (isOptimizedFalse) { > if (initsWhenFalse == FlowInfo.DEAD_END && allowFakeDeadBranch) { >- mergedInfo = initsWhenTrue.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD). >- unconditionalInits(); >+ if (!reportDeadCodeInKnownPattern) { >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=256796 >+ // do not report code even after if-else as dead as a consequence of analysis done in known dead code pattern >+ // when the CompilerOptions$reportDeadCodeInTrivialIfStatement option is disabled >+ if (ifStatement.thenStatement == null) { >+ mergedInfo = flowInfo.unconditionalInits(); >+ } else { >+ mergedInfo = initsWhenTrue.unconditionalInits(); >+ if (initsWhenTrue != FlowInfo.DEAD_END) { >+ // let the definitely false status of known dead code pattern not affect the reachability >+ mergedInfo.setReachMode(flowInfo.reachMode()); >+ } >+ } >+ } else { >+ mergedInfo = initsWhenTrue.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD). >+ unconditionalInits(); >+ } > } > else { > mergedInfo = >@@ -578,4 +609,10 @@ > */ > //https://bugs.eclipse.org/bugs/show_bug.cgi?id=303448 > abstract public boolean isMarkedAsNullOrNonNullInAssertExpression(LocalVariableBinding local); >+ >+/** >+ * Resets the definite and potential initialization info for the given local variable >+ * @param local >+ */ >+abstract public void resetAssignmentInfo(LocalVariableBinding local); > } >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LabelFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LabelFlowContext.java >index 3374313..88ca4e7 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LabelFlowContext.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LabelFlowContext.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -31,14 +31,14 @@ > > void checkLabelValidity(BlockScope scope) { > // check if label was already defined above >- FlowContext current = this.parent; >+ FlowContext current = this.getLocalParent(); > while (current != null) { > char[] currentLabelName; > if (((currentLabelName = current.labelName()) != null) > && CharOperation.equals(currentLabelName, this.labelName)) { > scope.problemReporter().alreadyDefinedLabel(this.labelName, this.associatedNode); > } >- current = current.parent; >+ current = current.getLocalParent(); > } > } > >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java >index 886fea6..2257835 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,13 +7,19 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >- * Stephan Herrmann - contribution for Bug 336428 - [compiler][null] bogus warning "redundant null check" in condition of do {} while() loop >+ * Stephan Herrmann - contributions for >+ * bug 336428 - [compiler][null] bogus warning "redundant null check" in condition of do {} while() loop >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 365519 - editorial cleanup after bug 186342 and bug 365387 >+ * bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.flow; > > import java.util.ArrayList; >+ > import org.eclipse.jdt.internal.compiler.ast.ASTNode; > import org.eclipse.jdt.internal.compiler.ast.Expression; >+import org.eclipse.jdt.internal.compiler.ast.FakedTrackingVariable; > import org.eclipse.jdt.internal.compiler.ast.Reference; > import org.eclipse.jdt.internal.compiler.codegen.BranchLabel; > import org.eclipse.jdt.internal.compiler.lookup.BlockScope; >@@ -21,6 +27,7 @@ > import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding; > import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; > import org.eclipse.jdt.internal.compiler.lookup.Scope; >+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; > import org.eclipse.jdt.internal.compiler.lookup.TypeIds; > import org.eclipse.jdt.internal.compiler.lookup.VariableBinding; > >@@ -43,10 +50,13 @@ > VariableBinding finalVariables[]; > int assignCount = 0; > >+ // the following three arrays are in sync regarding their indices: > LocalVariableBinding[] nullLocals; >- Expression[] nullReferences; >+ ASTNode[] nullReferences; // Expressions for null checking, Statements for resource analysis >+ // cast to Expression is safe if corresponding nullCheckType != EXIT_RESOURCE > int[] nullCheckTypes; > int nullCount; >+ // see also the related field FlowContext#expectedTypes > > // https://bugs.eclipse.org/bugs/show_bug.cgi?id=321926 > static private class EscapingExceptionCatchSite { >@@ -95,14 +105,14 @@ > if (variable == null) continue; > boolean complained = false; // remember if have complained on this final assignment > if (variable instanceof FieldBinding) { >- if (flowInfo.isPotentiallyAssigned((FieldBinding) variable)) { >+ if (flowInfo.isPotentiallyAssigned((FieldBinding)variable)) { > complained = true; > scope.problemReporter().duplicateInitializationOfBlankFinalField( > (FieldBinding) variable, > this.finalAssignments[i]); > } > } else { >- if (flowInfo.isPotentiallyAssigned((LocalVariableBinding) variable)) { >+ if (flowInfo.isPotentiallyAssigned((LocalVariableBinding)variable)) { > complained = true; > scope.problemReporter().duplicateInitializationOfFinalLocal( > (LocalVariableBinding) variable, >@@ -112,10 +122,10 @@ > // any reference reported at this level is removed from the parent context where it > // could also be reported again > if (complained) { >- FlowContext context = this.parent; >+ FlowContext context = this.getLocalParent(); > while (context != null) { > context.removeFinalAssignmentIfAny(this.finalAssignments[i]); >- context = context.parent; >+ context = context.getLocalParent(); > } > } > } >@@ -140,7 +150,7 @@ > // check only immutable null checks on innermost looping context > for (int i = 0; i < this.nullCount; i++) { > LocalVariableBinding local = this.nullLocals[i]; >- Expression expression = this.nullReferences[i]; >+ ASTNode location = this.nullReferences[i]; > // final local variable > switch (this.nullCheckTypes[i]) { > case CAN_ONLY_NON_NULL | IN_COMPARISON_NULL: >@@ -149,11 +159,11 @@ > this.nullReferences[i] = null; > if (this.nullCheckTypes[i] == (CAN_ONLY_NON_NULL | IN_COMPARISON_NON_NULL)) { > if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { >- scope.problemReporter().localVariableRedundantCheckOnNonNull(local, expression); >+ scope.problemReporter().localVariableRedundantCheckOnNonNull(local, location); > } > } else { > if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { >- scope.problemReporter().localVariableNonNullComparedToNull(local, expression); >+ scope.problemReporter().localVariableNonNullComparedToNull(local, location); > } > } > continue; >@@ -165,11 +175,11 @@ > this.nullReferences[i] = null; > if (this.nullCheckTypes[i] == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) { > if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { >- scope.problemReporter().localVariableRedundantCheckOnNonNull(local, expression); >+ scope.problemReporter().localVariableRedundantCheckOnNonNull(local, location); > } > } else { > if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { >- scope.problemReporter().localVariableNonNullComparedToNull(local, expression); >+ scope.problemReporter().localVariableNonNullComparedToNull(local, location); > } > } > continue; >@@ -178,11 +188,11 @@ > this.nullReferences[i] = null; > if (this.nullCheckTypes[i] == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL)) { > if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { >- scope.problemReporter().localVariableRedundantCheckOnNull(local, expression); >+ scope.problemReporter().localVariableRedundantCheckOnNull(local, location); > } > } else { > if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { >- scope.problemReporter().localVariableNullComparedToNonNull(local, expression); >+ scope.problemReporter().localVariableNullComparedToNonNull(local, location); > } > } > continue; >@@ -192,6 +202,7 @@ > case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL: > case CAN_ONLY_NULL | IN_ASSIGNMENT: > case CAN_ONLY_NULL | IN_INSTANCEOF: >+ Expression expression = (Expression)location; > if (flowInfo.isDefinitelyNull(local)) { > this.nullReferences[i] = null; > switch(this.nullCheckTypes[i] & CONTEXT_MASK) { >@@ -242,21 +253,39 @@ > case MAY_NULL: > if (flowInfo.isDefinitelyNull(local)) { > this.nullReferences[i] = null; >- scope.problemReporter().localVariableNullReference(local, expression); >+ scope.problemReporter().localVariableNullReference(local, location); > continue; > } >+ break; >+ case ASSIGN_TO_NONNULL: >+ this.parent.recordNullityMismatch(scope, (Expression)location, flowInfo.nullStatus(local), this.expectedTypes[i]); >+ break; >+ case EXIT_RESOURCE: >+ FakedTrackingVariable trackingVar = local.closeTracker; >+ if (trackingVar != null) { >+ if (trackingVar.hasDefinitelyNoResource(flowInfo)) { >+ continue; // no resource - no warning. >+ } >+ if (trackingVar.isClosedInFinallyOfEnclosing(scope)) { >+ continue; >+ } >+ if (this.parent.recordExitAgainstResource(scope, flowInfo, trackingVar, location)) { >+ this.nullReferences[i] = null; >+ continue; >+ } >+ } > break; > default: > // never happens > } >- this.parent.recordUsingNullReference(scope, local, expression, >+ this.parent.recordUsingNullReference(scope, local, location, > this.nullCheckTypes[i], flowInfo); > } > } > else { > // check inconsistent null checks on outermost looping context > for (int i = 0; i < this.nullCount; i++) { >- Expression expression = this.nullReferences[i]; >+ ASTNode location = this.nullReferences[i]; > // final local variable > LocalVariableBinding local = this.nullLocals[i]; > switch (this.nullCheckTypes[i]) { >@@ -266,11 +295,11 @@ > this.nullReferences[i] = null; > if (this.nullCheckTypes[i] == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) { > if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { >- scope.problemReporter().localVariableRedundantCheckOnNonNull(local, expression); >+ scope.problemReporter().localVariableRedundantCheckOnNonNull(local, location); > } > } else { > if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { >- scope.problemReporter().localVariableNonNullComparedToNull(local, expression); >+ scope.problemReporter().localVariableNonNullComparedToNull(local, location); > } > } > continue; >@@ -280,6 +309,7 @@ > case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL: > case CAN_ONLY_NULL | IN_ASSIGNMENT: > case CAN_ONLY_NULL | IN_INSTANCEOF: >+ Expression expression = (Expression) location; > if (flowInfo.isDefinitelyNull(local)) { > this.nullReferences[i] = null; > switch(this.nullCheckTypes[i] & CONTEXT_MASK) { >@@ -330,13 +360,39 @@ > case MAY_NULL: > if (flowInfo.isDefinitelyNull(local)) { > this.nullReferences[i] = null; >- scope.problemReporter().localVariableNullReference(local, expression); >+ scope.problemReporter().localVariableNullReference(local, location); > continue; > } > if (flowInfo.isPotentiallyNull(local)) { > this.nullReferences[i] = null; >- scope.problemReporter().localVariablePotentialNullReference(local, expression); >+ scope.problemReporter().localVariablePotentialNullReference(local, location); > continue; >+ } >+ break; >+ case ASSIGN_TO_NONNULL: >+ int nullStatus = flowInfo.nullStatus(local); >+ if (nullStatus != FlowInfo.NON_NULL) { >+ char[][] annotationName = scope.environment().getNonNullAnnotationName(); >+ scope.problemReporter().nullityMismatch((Expression) location, this.expectedTypes[i], nullStatus, annotationName); >+ } >+ break; >+ case EXIT_RESOURCE: >+ nullStatus = flowInfo.nullStatus(local); >+ if (nullStatus != FlowInfo.NON_NULL) { >+ FakedTrackingVariable closeTracker = local.closeTracker; >+ if (closeTracker != null) { >+ if (closeTracker.hasDefinitelyNoResource(flowInfo)) { >+ continue; // no resource - no warning. >+ } >+ if (closeTracker.isClosedInFinallyOfEnclosing(scope)) { >+ continue; >+ } >+ nullStatus = closeTracker.findMostSpecificStatus(flowInfo, scope, null); >+ closeTracker.recordErrorLocation(this.nullReferences[i], nullStatus); >+ closeTracker.reportRecordedErrors(scope, nullStatus); >+ this.nullReferences[i] = null; >+ continue; >+ } > } > break; > default: >@@ -396,6 +452,7 @@ > FlowContext inner = innerFlowContext; > while (inner != this && !(inner instanceof LoopingFlowContext)) { > inner = inner.parent; >+ // we know that inner is reachable from this without crossing a type boundary > } > if (inner == this) { > this.upstreamNullFlowInfo. >@@ -460,17 +517,17 @@ > } > > protected void recordNullReference(LocalVariableBinding local, >- Expression expression, int status) { >+ ASTNode expression, int status) { > if (this.nullCount == 0) { > this.nullLocals = new LocalVariableBinding[5]; >- this.nullReferences = new Expression[5]; >+ this.nullReferences = new ASTNode[5]; > this.nullCheckTypes = new int[5]; > } > else if (this.nullCount == this.nullLocals.length) { > System.arraycopy(this.nullLocals, 0, > this.nullLocals = new LocalVariableBinding[this.nullCount * 2], 0, this.nullCount); > System.arraycopy(this.nullReferences, 0, >- this.nullReferences = new Expression[this.nullCount * 2], 0, this.nullCount); >+ this.nullReferences = new ASTNode[this.nullCount * 2], 0, this.nullCount); > System.arraycopy(this.nullCheckTypes, 0, > this.nullCheckTypes = new int[this.nullCount * 2], 0, this.nullCount); > } >@@ -479,8 +536,26 @@ > this.nullCheckTypes[this.nullCount++] = status; > } > >+/** Record the fact that we see an early exit (in 'reference') while 'trackingVar' is in scope and may be unclosed. */ >+public boolean recordExitAgainstResource(BlockScope scope, FlowInfo flowInfo, FakedTrackingVariable trackingVar, ASTNode reference) { >+ LocalVariableBinding local = trackingVar.binding; >+ if (flowInfo.isDefinitelyNonNull(local)) { >+ return false; >+ } >+ if (flowInfo.isDefinitelyNull(local)) { >+ scope.problemReporter().unclosedCloseable(trackingVar, reference); >+ return true; // handled >+ } >+ if (flowInfo.isPotentiallyNull(local)) { >+ scope.problemReporter().potentiallyUnclosedCloseable(trackingVar, reference); >+ return true; // handled >+ } >+ recordNullReference(trackingVar.binding, reference, EXIT_RESOURCE); >+ return true; // handled >+} >+ > public void recordUsingNullReference(Scope scope, LocalVariableBinding local, >- Expression reference, int checkType, FlowInfo flowInfo) { >+ ASTNode location, int checkType, FlowInfo flowInfo) { > if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0 || > flowInfo.isDefinitelyUnknown(local)) { > return; >@@ -488,6 +563,7 @@ > switch (checkType) { > case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL: > case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL: >+ Expression reference = (Expression)location; > if (flowInfo.isDefinitelyNonNull(local)) { > if (checkType == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) { > if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { >@@ -547,6 +623,7 @@ > case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL: > case CAN_ONLY_NULL | IN_ASSIGNMENT: > case CAN_ONLY_NULL | IN_INSTANCEOF: >+ reference = (Expression)location; > if (flowInfo.isPotentiallyNonNull(local) > || flowInfo.isPotentiallyUnknown(local) > || flowInfo.isProtectedNonNull(local)) { >@@ -616,14 +693,14 @@ > return; > } > if (flowInfo.isDefinitelyNull(local)) { >- scope.problemReporter().localVariableNullReference(local, reference); >+ scope.problemReporter().localVariableNullReference(local, location); > return; > } > if (flowInfo.isPotentiallyNull(local)) { >- scope.problemReporter().localVariablePotentialNullReference(local, reference); >+ scope.problemReporter().localVariablePotentialNullReference(local, location); > return; > } >- recordNullReference(local, reference, checkType); >+ recordNullReference(local, location, checkType); > return; > default: > // never happens >@@ -666,4 +743,10 @@ > public boolean hasEscapingExceptions() { > return this.escapingExceptionCatchSites != null; > } >+ >+ protected boolean internalRecordNullityMismatch(Expression expression, int nullStatus, TypeBinding expectedType, int checkType) { >+ recordExpectedType(expectedType, this.nullCount); >+ recordNullReference(expression.localVariableBinding(), expression, checkType); >+ return true; >+ } > } >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java >index d5b5a3d..ed1ae7a 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java >@@ -13,6 +13,7 @@ > * bug 292478 - Report potentially null across variable assignment > * bug 332637 - Dead Code detection removing code that isn't dead > * bug 341499 - [compiler][null] allocate extra bits in all methods of UnconditionalFlowInfo >+ * bug 349326 - [1.7] new warning for missing try-with-resources > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.flow; > >@@ -770,7 +771,7 @@ > } > int vectorIndex; > if ((vectorIndex = (position / BitCacheSize) - 1) >- >= this.extra[0].length) { >+ >= this.extra[2].length) { > return false; // if not enough room in vector, then not initialized > } > return ((this.extra[2][vectorIndex] & this.extra[4][vectorIndex] >@@ -797,7 +798,7 @@ > } > int vectorIndex; > if ((vectorIndex = (position / BitCacheSize) - 1) >= >- this.extra[0].length) { >+ this.extra[2].length) { > return false; // if not enough room in vector, then not initialized > } > return ((this.extra[2][vectorIndex] & this.extra[3][vectorIndex] >@@ -822,7 +823,7 @@ > } > int vectorIndex; > if ((vectorIndex = (position / BitCacheSize) - 1) >= >- this.extra[0].length) { >+ this.extra[2].length) { > return false; // if not enough room in vector, then not initialized > } > return ((this.extra[2][vectorIndex] & this.extra[5][vectorIndex] >@@ -882,7 +883,7 @@ > } > int vectorIndex; > if ((vectorIndex = (position / BitCacheSize) - 1) >= >- this.extra[0].length) { >+ this.extra[2].length) { > return false; // if not enough room in vector, then not initialized > } > return ((this.extra[4][vectorIndex] >@@ -908,7 +909,7 @@ > } > int vectorIndex; > if ((vectorIndex = (position / BitCacheSize) - 1) >= >- this.extra[0].length) { >+ this.extra[2].length) { > return false; // if not enough room in vector, then not initialized > } > return ((this.extra[3][vectorIndex] >@@ -934,7 +935,7 @@ > } > int vectorIndex; > if ((vectorIndex = (position / BitCacheSize) - 1) >= >- this.extra[0].length) { >+ this.extra[2].length) { > return false; // if not enough room in vector, then not initialized > } > return (this.extra[5][vectorIndex] >@@ -2130,5 +2131,29 @@ > } > } > } >+ >+public void resetAssignmentInfo(LocalVariableBinding local) { >+ resetAssignmentInfo(local.id + this.maxFieldCount); >+} >+ >+public void resetAssignmentInfo(int position) { >+ if (this != DEAD_END) { >+ // position is zero-based >+ if (position < BitCacheSize) { >+ // use bits >+ long mask; >+ this.definiteInits &= (mask = ~(1L << position)); >+ this.potentialInits &= mask; >+ } else { >+ // use extra vector >+ int vectorIndex = (position / BitCacheSize) - 1; >+ if (this.extra == null || vectorIndex >= this.extra[0].length) return; // variable doesnt exist in flow info >+ long mask; >+ this.extra[0][vectorIndex] &= >+ (mask = ~(1L << (position % BitCacheSize))); >+ this.extra[1][vectorIndex] &= mask; >+ } >+ } >+} > } > >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java >index 5d705d6..93236ab 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -8,8 +8,13 @@ > * Contributors: > * IBM Corporation - initial API and implementation > * Benjamin Muskalla - Contribution for bug 239066 >- * Stephan Herrmann - Contribution for bug 236385 >- * Stephan Herrmann - Contribution for bug 295551 >+ * Stephan Herrmann - Contributions for >+ * bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used >+ * bug 295551 - Add option to automatically promote all warnings to errors >+ * bug 349326 - [1.7] new warning for missing try-with-resources >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 370639 - [compiler][resource] restore the default for resource leak warnings >+ * bug 366063 - Compiler should not add synthetic @NonNull annotations > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.impl; > >@@ -24,6 +29,7 @@ > import org.eclipse.jdt.internal.compiler.ast.ASTNode; > import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; > import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers; >+import org.eclipse.jdt.internal.compiler.lookup.TagBits; > import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities; > import org.eclipse.jdt.internal.compiler.util.Util; > >@@ -137,6 +143,22 @@ > public static final String OPTION_ReportMethodCanBeStatic = "org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic"; //$NON-NLS-1$ > public static final String OPTION_ReportMethodCanBePotentiallyStatic = "org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic"; //$NON-NLS-1$ > public static final String OPTION_ReportRedundantSpecificationOfTypeArguments = "org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments"; //$NON-NLS-1$ >+ public static final String OPTION_ReportUnclosedCloseable = "org.eclipse.jdt.core.compiler.problem.unclosedCloseable"; //$NON-NLS-1$ >+ public static final String OPTION_ReportPotentiallyUnclosedCloseable = "org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable"; //$NON-NLS-1$ >+ public static final String OPTION_ReportExplicitlyClosedAutoCloseable = "org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable"; //$NON-NLS-1$ >+ public static final String OPTION_ReportNullSpecViolation = "org.eclipse.jdt.core.compiler.problem.nullSpecViolation"; //$NON-NLS-1$ >+ public static final String OPTION_ReportPotentialNullSpecViolation = "org.eclipse.jdt.core.compiler.problem.potentialNullSpecViolation"; //$NON-NLS-1$ >+ public static final String OPTION_ReportNullSpecInsufficientInfo = "org.eclipse.jdt.core.compiler.problem.nullSpecInsufficientInfo"; //$NON-NLS-1$ >+ public static final String OPTION_ReportRedundantNullAnnotation = "org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation"; //$NON-NLS-1$ >+ public static final String OPTION_AnnotationBasedNullAnalysis = "org.eclipse.jdt.core.compiler.annotation.nullanalysis"; //$NON-NLS-1$ >+ public static final String OPTION_NullableAnnotationName = "org.eclipse.jdt.core.compiler.annotation.nullable"; //$NON-NLS-1$ >+ public static final String OPTION_NonNullAnnotationName = "org.eclipse.jdt.core.compiler.annotation.nonnull"; //$NON-NLS-1$ >+ public static final String OPTION_NonNullByDefaultAnnotationName = "org.eclipse.jdt.core.compiler.annotation.nonnullbydefault"; //$NON-NLS-1$ >+ // defaults for the above: >+ static final char[][] DEFAULT_NULLABLE_ANNOTATION_NAME = CharOperation.splitOn('.', "org.eclipse.jdt.annotation.Nullable".toCharArray()); //$NON-NLS-1$ >+ static final char[][] DEFAULT_NONNULL_ANNOTATION_NAME = CharOperation.splitOn('.', "org.eclipse.jdt.annotation.NonNull".toCharArray()); //$NON-NLS-1$ >+ static final char[][] DEFAULT_NONNULLBYDEFAULT_ANNOTATION_NAME = CharOperation.splitOn('.', "org.eclipse.jdt.annotation.NonNullByDefault".toCharArray()); //$NON-NLS-1$ >+ public static final String OPTION_NonNullIsDefault = "org.eclipse.jdt.core.compiler.annotation.nonnullisdefault"; //$NON-NLS-1$ > /** > * Possible values for configurable options > */ >@@ -240,6 +262,13 @@ > public static final int MethodCanBeStatic = IrritantSet.GROUP2 | ASTNode.Bit5; > public static final int MethodCanBePotentiallyStatic = IrritantSet.GROUP2 | ASTNode.Bit6; > public static final int RedundantSpecificationOfTypeArguments = IrritantSet.GROUP2 | ASTNode.Bit7; >+ public static final int UnclosedCloseable = IrritantSet.GROUP2 | ASTNode.Bit8; >+ public static final int PotentiallyUnclosedCloseable = IrritantSet.GROUP2 | ASTNode.Bit9; >+ public static final int ExplicitlyClosedAutoCloseable = IrritantSet.GROUP2 | ASTNode.Bit10; >+ public static final int NullSpecViolation = IrritantSet.GROUP2 | ASTNode.Bit11; >+ public static final int PotentialNullSpecViolation = IrritantSet.GROUP2 | ASTNode.Bit12; >+ public static final int NullSpecInsufficientInfo = IrritantSet.GROUP2 | ASTNode.Bit13; >+ public static final int RedundantNullAnnotation = IrritantSet.GROUP2 | ASTNode.Bit14; > > // Severity level for handlers > /** >@@ -362,6 +391,20 @@ > /** Controls whether forced generic type problems get reported */ > public boolean reportUnavoidableGenericTypeProblems; > >+ // === Support for Null Annotations: === >+ /** Master switch for null analysis based on annotations: */ >+ public boolean isAnnotationBasedNullAnalysisEnabled; >+ /** Fully qualified name of annotation to use as marker for nullable types. */ >+ public char[][] nullableAnnotationName; >+ /** Fully qualified name of annotation to use as marker for nonnull types. */ >+ public char[][] nonNullAnnotationName; >+ /** Fully qualified name of annotation to use as marker for default nonnull. */ >+ public char[][] nonNullByDefaultAnnotationName; >+ /** TagBits-encoded default for non-annotated types. */ >+ public long intendedDefaultNonNullness; // 0 or TagBits#AnnotationNonNull >+ /** Should resources (objects of type Closeable) be analysed for matching calls to close()? */ >+ public boolean analyseResourceLeaks; >+ > // keep in sync with warningTokenToIrritant and warningTokenFromIrritant > public final static String[] warningTokens = { > "all", //$NON-NLS-1$ >@@ -376,13 +419,15 @@ > "javadoc", //$NON-NLS-1$ > "nls", //$NON-NLS-1$ > "null", //$NON-NLS-1$ >- "restriction", //$NON-NLS-1$ > "rawtypes", //$NON-NLS-1$ >+ "resource", //$NON-NLS-1$ >+ "restriction", //$NON-NLS-1$ > "serial", //$NON-NLS-1$ > "static-access", //$NON-NLS-1$ > "static-method", //$NON-NLS-1$ > "super", //$NON-NLS-1$ > "synthetic-access", //$NON-NLS-1$ >+ "sync-override", //$NON-NLS-1$ > "unchecked", //$NON-NLS-1$ > "unqualified-field-access", //$NON-NLS-1$ > "unused", //$NON-NLS-1$ >@@ -551,6 +596,20 @@ > return OPTION_ReportMethodCanBePotentiallyStatic; > case RedundantSpecificationOfTypeArguments : > return OPTION_ReportRedundantSpecificationOfTypeArguments; >+ case UnclosedCloseable : >+ return OPTION_ReportUnclosedCloseable; >+ case PotentiallyUnclosedCloseable : >+ return OPTION_ReportPotentiallyUnclosedCloseable; >+ case ExplicitlyClosedAutoCloseable : >+ return OPTION_ReportExplicitlyClosedAutoCloseable; >+ case NullSpecViolation : >+ return OPTION_ReportNullSpecViolation; >+ case PotentialNullSpecViolation : >+ return OPTION_ReportPotentialNullSpecViolation; >+ case NullSpecInsufficientInfo : >+ return OPTION_ReportNullSpecInsufficientInfo; >+ case RedundantNullAnnotation : >+ return OPTION_ReportRedundantNullAnnotation; > } > return null; > } >@@ -714,6 +773,18 @@ > OPTION_ReportUnusedTypeArgumentsForMethodInvocation, > OPTION_ReportUnusedWarningToken, > OPTION_ReportVarargsArgumentNeedCast, >+ OPTION_ReportUnclosedCloseable, >+ OPTION_ReportPotentiallyUnclosedCloseable, >+ OPTION_ReportExplicitlyClosedAutoCloseable, >+ OPTION_AnnotationBasedNullAnalysis, >+ OPTION_NonNullAnnotationName, >+ OPTION_NullableAnnotationName, >+ OPTION_NonNullByDefaultAnnotationName, >+ OPTION_NonNullIsDefault, >+ OPTION_ReportNullSpecViolation, >+ OPTION_ReportPotentialNullSpecViolation, >+ OPTION_ReportNullSpecInsufficientInfo, >+ OPTION_ReportRedundantNullAnnotation > }; > return result; > } >@@ -776,6 +847,10 @@ > case NullReference : > case PotentialNullReference : > case RedundantNullCheck : >+ case NullSpecViolation : >+ case PotentialNullSpecViolation : >+ case NullSpecInsufficientInfo : >+ case RedundantNullAnnotation : > return "null"; //$NON-NLS-1$ > case FallthroughCase : > return "fallthrough"; //$NON-NLS-1$ >@@ -784,10 +859,16 @@ > case MethodCanBeStatic : > case MethodCanBePotentiallyStatic : > return "static-method"; //$NON-NLS-1$ >+ case PotentiallyUnclosedCloseable: >+ case UnclosedCloseable: >+ case ExplicitlyClosedAutoCloseable: >+ return "resource"; //$NON-NLS-1$ > case InvalidJavadoc : > case MissingJavadocComments : > case MissingJavadocTags: >- return "javadoc"; //$NON-NLS-1$ >+ return "javadoc"; //$NON-NLS-1$ >+ case MissingSynchronizedModifierInInheritedMethod: >+ return "sync-override"; //$NON-NLS-1$ > } > return null; > } >@@ -841,6 +922,8 @@ > case 'r' : > if ("rawtypes".equals(warningToken)) //$NON-NLS-1$ > return IrritantSet.RAW; >+ if ("resource".equals(warningToken)) //$NON-NLS-1$ >+ return IrritantSet.RESOURCE; > if ("restriction".equals(warningToken)) //$NON-NLS-1$ > return IrritantSet.RESTRICTION; > break; >@@ -856,6 +939,8 @@ > if ("super".equals(warningToken)) { //$NON-NLS-1$ > return IrritantSet.SUPER; > } >+ if ("sync-override".equals(warningToken)) //$NON-NLS-1$ >+ return IrritantSet.SYNCHRONIZED; > break; > case 'u' : > if ("unused".equals(warningToken)) //$NON-NLS-1$ >@@ -980,6 +1065,21 @@ > optionsMap.put(OPTION_ReportMethodCanBeStatic, getSeverityString(MethodCanBeStatic)); > optionsMap.put(OPTION_ReportMethodCanBePotentiallyStatic, getSeverityString(MethodCanBePotentiallyStatic)); > optionsMap.put(OPTION_ReportRedundantSpecificationOfTypeArguments, getSeverityString(RedundantSpecificationOfTypeArguments)); >+ optionsMap.put(OPTION_ReportUnclosedCloseable, getSeverityString(UnclosedCloseable)); >+ optionsMap.put(OPTION_ReportPotentiallyUnclosedCloseable, getSeverityString(PotentiallyUnclosedCloseable)); >+ optionsMap.put(OPTION_ReportExplicitlyClosedAutoCloseable, getSeverityString(ExplicitlyClosedAutoCloseable)); >+ optionsMap.put(OPTION_AnnotationBasedNullAnalysis, this.isAnnotationBasedNullAnalysisEnabled ? ENABLED : DISABLED); >+ optionsMap.put(OPTION_ReportNullSpecViolation, getSeverityString(NullSpecViolation)); >+ optionsMap.put(OPTION_ReportPotentialNullSpecViolation, getSeverityString(PotentialNullSpecViolation)); >+ optionsMap.put(OPTION_ReportNullSpecInsufficientInfo, getSeverityString(NullSpecInsufficientInfo)); >+ optionsMap.put(OPTION_ReportRedundantNullAnnotation, getSeverityString(RedundantNullAnnotation)); >+ optionsMap.put(OPTION_NullableAnnotationName, String.valueOf(CharOperation.concatWith(this.nullableAnnotationName, '.'))); >+ optionsMap.put(OPTION_NonNullAnnotationName, String.valueOf(CharOperation.concatWith(this.nonNullAnnotationName, '.'))); >+ optionsMap.put(OPTION_NonNullByDefaultAnnotationName, String.valueOf(CharOperation.concatWith(this.nonNullByDefaultAnnotationName, '.'))); >+ if (this.intendedDefaultNonNullness == TagBits.AnnotationNonNull) >+ optionsMap.put(OPTION_NonNullIsDefault, CompilerOptions.ENABLED); >+ else >+ optionsMap.put(OPTION_NonNullIsDefault, CompilerOptions.DISABLED); > return optionsMap; > } > >@@ -1130,6 +1230,14 @@ > > // allow null info from asserts to be considered downstream by default > this.includeNullInfoFromAsserts = false; >+ >+ this.isAnnotationBasedNullAnalysisEnabled = false; >+ this.nullableAnnotationName = DEFAULT_NULLABLE_ANNOTATION_NAME; >+ this.nonNullAnnotationName = DEFAULT_NONNULL_ANNOTATION_NAME; >+ this.nonNullByDefaultAnnotationName = DEFAULT_NONNULLBYDEFAULT_ANNOTATION_NAME; >+ this.intendedDefaultNonNullness = 0; >+ >+ this.analyseResourceLeaks = true; > } > > public void set(Map optionsMap) { >@@ -1410,6 +1518,49 @@ > if ((optionValue = optionsMap.get(OPTION_ReportMethodCanBeStatic)) != null) updateSeverity(MethodCanBeStatic, optionValue); > if ((optionValue = optionsMap.get(OPTION_ReportMethodCanBePotentiallyStatic)) != null) updateSeverity(MethodCanBePotentiallyStatic, optionValue); > if ((optionValue = optionsMap.get(OPTION_ReportRedundantSpecificationOfTypeArguments)) != null) updateSeverity(RedundantSpecificationOfTypeArguments, optionValue); >+ if ((optionValue = optionsMap.get(OPTION_ReportUnclosedCloseable)) != null) updateSeverity(UnclosedCloseable, optionValue); >+ if ((optionValue = optionsMap.get(OPTION_ReportPotentiallyUnclosedCloseable)) != null) updateSeverity(PotentiallyUnclosedCloseable, optionValue); >+ if ((optionValue = optionsMap.get(OPTION_ReportExplicitlyClosedAutoCloseable)) != null) updateSeverity(ExplicitlyClosedAutoCloseable, optionValue); >+ if (getSeverity(UnclosedCloseable) == ProblemSeverities.Ignore >+ && getSeverity(PotentiallyUnclosedCloseable) == ProblemSeverities.Ignore >+ && getSeverity(ExplicitlyClosedAutoCloseable) == ProblemSeverities.Ignore) { >+ this.analyseResourceLeaks = false; >+ } else { >+ this.analyseResourceLeaks = true; >+ } >+ if ((optionValue = optionsMap.get(OPTION_AnnotationBasedNullAnalysis)) != null) { >+ this.isAnnotationBasedNullAnalysisEnabled = ENABLED.equals(optionValue); >+ } >+ if (this.isAnnotationBasedNullAnalysisEnabled) { >+ if ((optionValue = optionsMap.get(OPTION_ReportNullSpecViolation)) != null) { >+ if (ERROR.equals(optionValue)) { >+ this.errorThreshold.set(NullSpecViolation); >+ this.warningThreshold.clear(NullSpecViolation); >+ } else if (WARNING.equals(optionValue)) { >+ this.errorThreshold.clear(NullSpecViolation); >+ this.warningThreshold.set(NullSpecViolation); >+ } >+ // "ignore" is not valid for this option >+ } >+ if ((optionValue = optionsMap.get(OPTION_ReportPotentialNullSpecViolation)) != null) updateSeverity(PotentialNullSpecViolation, optionValue); >+ if ((optionValue = optionsMap.get(OPTION_ReportNullSpecInsufficientInfo)) != null) updateSeverity(NullSpecInsufficientInfo, optionValue); >+ if ((optionValue = optionsMap.get(OPTION_ReportRedundantNullAnnotation)) != null) updateSeverity(RedundantNullAnnotation, optionValue); >+ if ((optionValue = optionsMap.get(OPTION_NullableAnnotationName)) != null) { >+ this.nullableAnnotationName = CharOperation.splitAndTrimOn('.', ((String)optionValue).toCharArray()); >+ } >+ if ((optionValue = optionsMap.get(OPTION_NonNullAnnotationName)) != null) { >+ this.nonNullAnnotationName = CharOperation.splitAndTrimOn('.', ((String)optionValue).toCharArray()); >+ } >+ if ((optionValue = optionsMap.get(OPTION_NonNullByDefaultAnnotationName)) != null) { >+ this.nonNullByDefaultAnnotationName = CharOperation.splitAndTrimOn('.', ((String)optionValue).toCharArray()); >+ } >+ if ((optionValue = optionsMap.get(OPTION_NonNullIsDefault)) != null) { >+ if (CompilerOptions.ENABLED.equals(optionValue)) >+ this.intendedDefaultNonNullness = TagBits.AnnotationNonNull; >+ else if (CompilerOptions.DISABLED.equals(optionValue)) >+ this.intendedDefaultNonNullness = 0; >+ } >+ } > > // Javadoc options > if ((optionValue = optionsMap.get(OPTION_DocCommentSupport)) != null) { >@@ -1625,6 +1776,9 @@ > buf.append("\n\t- method can be static: ").append(getSeverityString(MethodCanBeStatic)); //$NON-NLS-1$ > buf.append("\n\t- method can be potentially static: ").append(getSeverityString(MethodCanBePotentiallyStatic)); //$NON-NLS-1$ > buf.append("\n\t- redundant specification of type arguments: ").append(getSeverityString(RedundantSpecificationOfTypeArguments)); //$NON-NLS-1$ >+ buf.append("\n\t- resource is not closed: ").append(getSeverityString(UnclosedCloseable)); //$NON-NLS-1$ >+ buf.append("\n\t- resource may not be closed: ").append(getSeverityString(PotentiallyUnclosedCloseable)); //$NON-NLS-1$ >+ buf.append("\n\t- resource should be handled by try-with-resources: ").append(getSeverityString(ExplicitlyClosedAutoCloseable)); //$NON-NLS-1$ > return buf.toString(); > } > >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java >index db1823b..d526c4e 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,6 +7,10 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contributions for >+ * bug 349326 - [1.7] new warning for missing try-with-resources >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 370639 - [compiler][resource] restore the default for resource leak warnings > *******************************************************************************/ > > package org.eclipse.jdt.internal.compiler.impl; >@@ -53,10 +57,12 @@ > public static final IrritantSet STATIC_ACCESS = new IrritantSet(CompilerOptions.IndirectStaticAccess); > public static final IrritantSet STATIC_METHOD = new IrritantSet(CompilerOptions.MethodCanBeStatic); > public static final IrritantSet SYNTHETIC_ACCESS = new IrritantSet(CompilerOptions.AccessEmulation); >+ public static final IrritantSet SYNCHRONIZED = new IrritantSet(CompilerOptions.MissingSynchronizedModifierInInheritedMethod); > public static final IrritantSet SUPER = new IrritantSet(CompilerOptions.OverridingMethodWithoutSuperInvocation); > public static final IrritantSet UNUSED = new IrritantSet(CompilerOptions.UnusedLocalVariable); > public static final IrritantSet UNCHECKED = new IrritantSet(CompilerOptions.UncheckedTypeOperation); > public static final IrritantSet UNQUALIFIED_FIELD_ACCESS = new IrritantSet(CompilerOptions.UnqualifiedFieldAccess); >+ public static final IrritantSet RESOURCE = new IrritantSet(CompilerOptions.UnclosedCloseable); > > public static final IrritantSet JAVADOC = new IrritantSet(CompilerOptions.InvalidJavadoc); > public static final IrritantSet COMPILER_DEFAULT_ERRORS = new IrritantSet(0); // no optional error by default >@@ -99,8 +105,15 @@ > // group-2 warnings enabled by default > .set( > CompilerOptions.DeadCode >- |CompilerOptions.Tasks); >- >+ |CompilerOptions.Tasks >+ |CompilerOptions.UnclosedCloseable >+ |CompilerOptions.NullSpecInsufficientInfo >+ |CompilerOptions.RedundantNullAnnotation); >+ // default errors IF AnnotationBasedNullAnalysis is enabled: >+ COMPILER_DEFAULT_ERRORS.set( >+ CompilerOptions.NullSpecViolation >+ |CompilerOptions.PotentialNullSpecViolation); >+ > ALL.setAll(); > HIDING > .set(CompilerOptions.FieldHiding) >@@ -108,7 +121,12 @@ > .set(CompilerOptions.TypeHiding); > NULL > .set(CompilerOptions.PotentialNullReference) >- .set(CompilerOptions.RedundantNullCheck); >+ .set(CompilerOptions.RedundantNullCheck) >+ .set(CompilerOptions.NullSpecViolation) >+ .set(CompilerOptions.PotentialNullSpecViolation) >+ .set(CompilerOptions.NullSpecInsufficientInfo) >+ .set(CompilerOptions.RedundantNullAnnotation); >+ > RESTRICTION.set(CompilerOptions.DiscouragedReference); > STATIC_ACCESS.set(CompilerOptions.NonStaticAccessToStatic); > UNUSED >@@ -124,6 +142,9 @@ > .set(CompilerOptions.RedundantSpecificationOfTypeArguments); > STATIC_METHOD > .set(CompilerOptions.MethodCanBePotentiallyStatic); >+ RESOURCE >+ .set(CompilerOptions.PotentiallyUnclosedCloseable) >+ .set(CompilerOptions.ExplicitlyClosedAutoCloseable); > String suppressRawWhenUnchecked = System.getProperty("suppressRawWhenUnchecked"); //$NON-NLS-1$ > if (suppressRawWhenUnchecked != null && "true".equalsIgnoreCase(suppressRawWhenUnchecked)) { //$NON-NLS-1$ > UNCHECKED.set(CompilerOptions.RawTypeReference); >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ReferenceContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ReferenceContext.java >index ec3f72b..6c93b26 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ReferenceContext.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ReferenceContext.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -18,6 +18,7 @@ > > import org.eclipse.jdt.core.compiler.CategorizedProblem; > import org.eclipse.jdt.internal.compiler.CompilationResult; >+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; > > public interface ReferenceContext { > >@@ -25,7 +26,10 @@ > > CompilationResult compilationResult(); > >+ CompilationUnitDeclaration getCompilationUnitDeclaration(); >+ > boolean hasErrors(); > > void tagAsHavingErrors(); >+ > } >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationBinding.java >index c88c4a1..038c5ad 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationBinding.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationBinding.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -54,11 +54,10 @@ > count++; > if ((annotationTagBits & TagBits.AnnotationSafeVarargs) != 0) > count++; >- if ((annotationTagBits & TagBits.AnnotationPostConstruct) != 0) >- count++; >- if ((annotationTagBits & TagBits.AnnotationPreDestroy) != 0) >- count++; >- // count must be different from 0 >+ if (count == 0) { >+ // this is possible if bits were set for null annotations >+ return recordedAnnotations; >+ } > > int index = recordedAnnotations.length; > AnnotationBinding[] result = new AnnotationBinding[index + count]; >@@ -81,10 +80,6 @@ > result[index++] = buildMarkerAnnotationForMemberType(TypeConstants.JAVA_LANG_INVOKE_METHODHANDLE_$_POLYMORPHICSIGNATURE, env); > if ((annotationTagBits & TagBits.AnnotationSafeVarargs) != 0) > result[index++] = buildMarkerAnnotation(TypeConstants.JAVA_LANG_SAFEVARARGS, env); >- if ((annotationTagBits & TagBits.AnnotationPostConstruct) != 0) >- result[index++] = buildMarkerAnnotation(TypeConstants.JAVAX_ANNOTATION_POSTCONSTRUCT, env); >- if ((annotationTagBits & TagBits.AnnotationPreDestroy) != 0) >- result[index++] = buildMarkerAnnotation(TypeConstants.JAVAX_ANNOTATION_PREDESTROY, env); > return result; > } > >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java >index 71e2971..3f40018 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,6 +7,13 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contributions for >+ * bug 349326 - [1.7] new warning for missing try-with-resources >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 364890 - BinaryTypeBinding should use char constants from Util >+ * bug 365387 - [compiler][null] bug 186342: Issues to follow up post review and verification. >+ * bug 358903 - Filter practically unimportant resource leak warnings >+ * bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.lookup; > >@@ -15,9 +22,11 @@ > import org.eclipse.jdt.core.compiler.CharOperation; > import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; > import org.eclipse.jdt.internal.compiler.env.*; >+import org.eclipse.jdt.internal.compiler.impl.BooleanConstant; > import org.eclipse.jdt.internal.compiler.impl.Constant; > import org.eclipse.jdt.internal.compiler.problem.AbortCompilation; > import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable; >+import org.eclipse.jdt.internal.compiler.util.Util; > > /* > Not all fields defined by this type are initialized when it is created. >@@ -155,7 +164,7 @@ > of generics. > */ > char[] typeSignature = binaryType.getGenericSignature(); >- this.typeVariables = typeSignature != null && typeSignature.length > 0 && typeSignature[0] == '<' >+ this.typeVariables = typeSignature != null && typeSignature.length > 0 && typeSignature[0] == Util.C_GENERIC_START > ? null // is initialized in cachePartsFrom (called from LookupEnvironment.createBinaryTypeFrom())... must set to null so isGenericType() answers true > : Binding.NO_TYPE_VARIABLES; > >@@ -178,7 +187,7 @@ > // attempt to find the enclosing type if it exists in the cache (otherwise - resolve it when requested) > this.enclosingType = environment.getTypeFromConstantPoolName(enclosingTypeName, 0, -1, true, null /* could not be missing */); // pretend parameterized to avoid raw > this.tagBits |= TagBits.MemberTypeMask; // must be a member type not a top-level or local type >- this.tagBits |= TagBits.HasUnresolvedEnclosingType; >+ this.tagBits |= TagBits.HasUnresolvedEnclosingType; > if (enclosingType().isStrictfp()) > this.modifiers |= ClassFileConstants.AccStrictfp; > if (enclosingType().isDeprecated()) >@@ -283,10 +292,11 @@ > int size = memberTypeStructures.length; > if (size > 0) { > this.memberTypes = new ReferenceBinding[size]; >- for (int i = 0; i < size; i++) >+ for (int i = 0; i < size; i++) { > // attempt to find each member type if it exists in the cache (otherwise - resolve it when requested) > this.memberTypes[i] = this.environment.getTypeFromConstantPoolName(memberTypeStructures[i].getName(), 0, -1, false, null /* could not be missing */); >- this.tagBits |= TagBits.HasUnresolvedMemberTypes; >+ } >+ this.tagBits |= TagBits.HasUnresolvedMemberTypes; > } > } > >@@ -304,7 +314,7 @@ > if (typeSignature != null) { > // ClassSignature = ParameterPart(optional) super_TypeSignature interface_signature > wrapper = new SignatureWrapper(typeSignature); >- if (wrapper.signature[wrapper.start] == '<') { >+ if (wrapper.signature[wrapper.start] == Util.C_GENERIC_START) { > // ParameterPart = '<' ParameterSignature(s) '>' > wrapper.start++; // skip '<' > this.typeVariables = createTypeVariables(wrapper, true, missingTypeNames); >@@ -358,6 +368,11 @@ > types.toArray(this.superInterfaces); > this.tagBits |= TagBits.HasUnresolvedSuperinterfaces; > } >+ } >+ >+ // need type annotations before processing methods (for @NonNullByDefault) >+ if (this.environment.globalOptions.isAnnotationBasedNullAnalysisEnabled) { >+ scanTypeForNullDefaultAnnotation(binaryType); > } > > if (needFieldsAndMethods) { >@@ -459,11 +474,11 @@ > int numOfParams = 0; > char nextChar; > int index = 0; // first character is always '(' so skip it >- while ((nextChar = methodDescriptor[++index]) != ')') { >- if (nextChar != '[') { >+ while ((nextChar = methodDescriptor[++index]) != Util.C_PARAM_END) { >+ if (nextChar != Util.C_ARRAY) { > numOfParams++; >- if (nextChar == 'L') >- while ((nextChar = methodDescriptor[++index]) != ';'){/*empty*/} >+ if (nextChar == Util.C_RESOLVED) >+ while ((nextChar = methodDescriptor[++index]) != Util.C_NAME_END){/*empty*/} > } > } > >@@ -487,9 +502,9 @@ > index = 1; > int end = 0; // first character is always '(' so skip it > for (int i = 0; i < numOfParams; i++) { >- while ((nextChar = methodDescriptor[++end]) == '['){/*empty*/} >- if (nextChar == 'L') >- while ((nextChar = methodDescriptor[++end]) != ';'){/*empty*/} >+ while ((nextChar = methodDescriptor[++end]) == Util.C_ARRAY){/*empty*/} >+ if (nextChar == Util.C_RESOLVED) >+ while ((nextChar = methodDescriptor[++end]) != Util.C_NAME_END){/*empty*/} > > if (i >= startIndex) { // skip the synthetic arg if necessary > parameters[i - startIndex] = this.environment.getTypeFromSignature(methodDescriptor, index, end, false, this, missingTypeNames); >@@ -518,7 +533,7 @@ > methodModifiers |= ExtraCompilerModifiers.AccGenericSignature; > // MethodTypeSignature = ParameterPart(optional) '(' TypeSignatures ')' return_typeSignature ['^' TypeSignature (optional)] > SignatureWrapper wrapper = new SignatureWrapper(methodSignature, use15specifics); >- if (wrapper.signature[wrapper.start] == '<') { >+ if (wrapper.signature[wrapper.start] == Util.C_GENERIC_START) { > // <A::Ljava/lang/annotation/Annotation;>(Ljava/lang/Class<TA;>;)TA; > // ParameterPart = '<' ParameterSignature(s) '>' > wrapper.start++; // skip '<' >@@ -526,13 +541,13 @@ > wrapper.start++; // skip '>' > } > >- if (wrapper.signature[wrapper.start] == '(') { >+ if (wrapper.signature[wrapper.start] == Util.C_PARAM_START) { > wrapper.start++; // skip '(' >- if (wrapper.signature[wrapper.start] == ')') { >+ if (wrapper.signature[wrapper.start] == Util.C_PARAM_END) { > wrapper.start++; // skip ')' > } else { > java.util.ArrayList types = new java.util.ArrayList(2); >- while (wrapper.signature[wrapper.start] != ')') >+ while (wrapper.signature[wrapper.start] != Util.C_PARAM_END) > types.add(this.environment.getTypeFromTypeSignature(wrapper, typeVars, this, missingTypeNames)); > wrapper.start++; // skip ')' > int numParam = types.size(); >@@ -549,13 +564,13 @@ > // always retrieve return type (for constructors, its V for void - will be ignored) > returnType = this.environment.getTypeFromTypeSignature(wrapper, typeVars, this, missingTypeNames); > >- if (!wrapper.atEnd() && wrapper.signature[wrapper.start] == '^') { >+ if (!wrapper.atEnd() && wrapper.signature[wrapper.start] == Util.C_EXCEPTION_START) { > // attempt to find each exception if it exists in the cache (otherwise - resolve it when requested) > java.util.ArrayList types = new java.util.ArrayList(2); > do { > wrapper.start++; // skip '^' > types.add(this.environment.getTypeFromTypeSignature(wrapper, typeVars, this, missingTypeNames)); >- } while (!wrapper.atEnd() && wrapper.signature[wrapper.start] == '^'); >+ } while (!wrapper.atEnd() && wrapper.signature[wrapper.start] == Util.C_EXCEPTION_START); > exceptions = new ReferenceBinding[types.size()]; > types.toArray(exceptions); > } else { // get the exceptions the old way >@@ -587,6 +602,9 @@ > // fixup the declaring element of the type variable > for (int i = 0, length = typeVars.length; i < length; i++) > typeVars[i].declaringElement = result; >+ >+ scanMethodForNullAnnotation(method, result); >+ > return result; > } > >@@ -610,7 +628,7 @@ > total--; > } else if (iClinit == -1) { > char[] methodName = method.getSelector(); >- if (methodName.length == 8 && methodName[0] == '<') { >+ if (methodName.length == 8 && methodName[0] == Util.C_GENERIC_START) { > // discard <clinit> > iClinit = i; > total--; >@@ -655,21 +673,21 @@ > createVariables: { > for (int i = 1; i < length; i++) { > switch(typeSignature[i]) { >- case '<' : >+ case Util.C_GENERIC_START : > depth++; > break; >- case '>' : >+ case Util.C_GENERIC_END : > if (--depth < 0) > break createVariables; > break; >- case ';' : >- if ((depth == 0) && (i +1 < length) && (typeSignature[i+1] != ':')) >+ case Util.C_NAME_END : >+ if ((depth == 0) && (i +1 < length) && (typeSignature[i+1] != Util.C_COLON)) > pendingVariable = true; > break; > default: > if (pendingVariable) { > pendingVariable = false; >- int colon = CharOperation.indexOf(':', typeSignature, i); >+ int colon = CharOperation.indexOf(Util.C_COLON, typeSignature, i); > char[] variableName = CharOperation.subarray(typeSignature, i, colon); > variables.add(new TypeVariableBinding(variableName, this, rank++, this.environment)); > } >@@ -722,7 +740,7 @@ > > private MethodBinding findMethod(char[] methodDescriptor, char[][][] missingTypeNames) { > int index = -1; >- while (methodDescriptor[++index] != '(') { >+ while (methodDescriptor[++index] != Util.C_PARAM_START) { > // empty > } > char[] selector = new char[index]; >@@ -731,11 +749,11 @@ > int numOfParams = 0; > char nextChar; > int paramStart = index; >- while ((nextChar = methodDescriptor[++index]) != ')') { >- if (nextChar != '[') { >+ while ((nextChar = methodDescriptor[++index]) != Util.C_PARAM_END) { >+ if (nextChar != Util.C_ARRAY) { > numOfParams++; >- if (nextChar == 'L') >- while ((nextChar = methodDescriptor[++index]) != ';'){/*empty*/} >+ if (nextChar == Util.C_RESOLVED) >+ while ((nextChar = methodDescriptor[++index]) != Util.C_NAME_END){/*empty*/} > } > } > if (numOfParams > 0) { >@@ -743,9 +761,9 @@ > index = paramStart + 1; > int end = paramStart; // first character is always '(' so skip it > for (int i = 0; i < numOfParams; i++) { >- while ((nextChar = methodDescriptor[++end]) == '['){/*empty*/} >- if (nextChar == 'L') >- while ((nextChar = methodDescriptor[++end]) != ';'){/*empty*/} >+ while ((nextChar = methodDescriptor[++end]) == Util.C_ARRAY){/*empty*/} >+ if (nextChar == Util.C_RESOLVED) >+ while ((nextChar = methodDescriptor[++end]) != Util.C_NAME_END){/*empty*/} > > TypeBinding param = this.environment.getTypeFromSignature(methodDescriptor, index, end, false, this, missingTypeNames); > if (param instanceof UnresolvedReferenceBinding) { >@@ -971,14 +989,26 @@ > variable.resolve(); > return variable; > } >+public boolean hasTypeBit(int bit) { >+ // ensure hierarchy is resolved, which will propagate bits down to us >+ boolean wasToleratingMissingTypeProcessingAnnotations = this.environment.mayTolerateMissingType; >+ this.environment.mayTolerateMissingType = true; >+ try { >+ superclass(); >+ superInterfaces(); >+ } finally { >+ this.environment.mayTolerateMissingType = wasToleratingMissingTypeProcessingAnnotations; >+ } >+ return (this.typeBits & bit) != 0; >+} > private void initializeTypeVariable(TypeVariableBinding variable, TypeVariableBinding[] existingVariables, SignatureWrapper wrapper, char[][][] missingTypeNames) { > // ParameterSignature = Identifier ':' TypeSignature > // or Identifier ':' TypeSignature(optional) InterfaceBound(s) > // InterfaceBound = ':' TypeSignature >- int colon = CharOperation.indexOf(':', wrapper.signature, wrapper.start); >+ int colon = CharOperation.indexOf(Util.C_COLON, wrapper.signature, wrapper.start); > wrapper.start = colon + 1; // skip name + ':' > ReferenceBinding type, firstBound = null; >- if (wrapper.signature[wrapper.start] == ':') { >+ if (wrapper.signature[wrapper.start] == Util.C_COLON) { > type = this.environment.getResolvedType(TypeConstants.JAVA_LANG_OBJECT, null); > } else { > TypeBinding typeFromTypeSignature = this.environment.getTypeFromTypeSignature(wrapper, existingVariables, this, missingTypeNames); >@@ -996,12 +1026,12 @@ > variable.superclass = type; > > ReferenceBinding[] bounds = null; >- if (wrapper.signature[wrapper.start] == ':') { >+ if (wrapper.signature[wrapper.start] == Util.C_COLON) { > java.util.ArrayList types = new java.util.ArrayList(2); > do { > wrapper.start++; // skip ':' > types.add(this.environment.getTypeFromTypeSignature(wrapper, existingVariables, this, missingTypeNames)); >- } while (wrapper.signature[wrapper.start] == ':'); >+ } while (wrapper.signature[wrapper.start] == Util.C_COLON); > bounds = new ReferenceBinding[types.size()]; > types.toArray(bounds); > } >@@ -1128,6 +1158,139 @@ > } > return this.storedAnnotations; > } >+void scanMethodForNullAnnotation(IBinaryMethod method, MethodBinding methodBinding) { >+ if (!this.environment.globalOptions.isAnnotationBasedNullAnalysisEnabled) >+ return; >+ char[][] nullableAnnotationName = this.environment.getNullableAnnotationName(); >+ char[][] nonNullAnnotationName = this.environment.getNonNullAnnotationName(); >+ char[][] nonNullByDefaultAnnotationName = this.environment.getNonNullByDefaultAnnotationName(); >+ if (nullableAnnotationName == null || nonNullAnnotationName == null || nonNullByDefaultAnnotationName == null) >+ return; // not well-configured to use null annotations >+ >+ int currentDefault = NO_NULL_DEFAULT; >+ if ((this.tagBits & TagBits.AnnotationNonNullByDefault) != 0) { >+ currentDefault = NONNULL_BY_DEFAULT; >+ } else if ((this.tagBits & TagBits.AnnotationNullUnspecifiedByDefault) != 0) { >+ currentDefault = NULL_UNSPECIFIED_BY_DEFAULT; >+ } >+ >+ // return: >+ IBinaryAnnotation[] annotations = method.getAnnotations(); >+ boolean explicitNullness = false; >+ if (annotations != null) { >+ for (int i = 0; i < annotations.length; i++) { >+ char[] annotationTypeName = annotations[i].getTypeName(); >+ if (annotationTypeName[0] != Util.C_RESOLVED) >+ continue; >+ char[][] typeName = CharOperation.splitOn('/', annotationTypeName, 1, annotationTypeName.length-1); // cut of leading 'L' and trailing ';' >+ if (CharOperation.equals(typeName, nonNullByDefaultAnnotationName)) { >+ methodBinding.tagBits |= TagBits.AnnotationNonNullByDefault; >+ currentDefault = NONNULL_BY_DEFAULT; >+ } >+ if (!explicitNullness && CharOperation.equals(typeName, nonNullAnnotationName)) { >+ methodBinding.tagBits |= TagBits.AnnotationNonNull; >+ explicitNullness = true; >+ } >+ if (!explicitNullness && CharOperation.equals(typeName, nullableAnnotationName)) { >+ methodBinding.tagBits |= TagBits.AnnotationNullable; >+ explicitNullness = true; >+ } >+ } >+ } >+ if (!explicitNullness && currentDefault == NONNULL_BY_DEFAULT) { >+ methodBinding.tagBits |= TagBits.AnnotationNonNull; >+ } >+ >+ // parameters: >+ TypeBinding[] parameters = methodBinding.parameters; >+ int numVisibleParams = parameters.length; >+ int numParamAnnotations = method.getAnnotatedParametersCount(); >+ if (numParamAnnotations > 0 || currentDefault == NONNULL_BY_DEFAULT) { >+ for (int j = 0; j < numVisibleParams; j++) { >+ explicitNullness = false; >+ if (numParamAnnotations > 0) { >+ int startIndex = numParamAnnotations - numVisibleParams; >+ IBinaryAnnotation[] paramAnnotations = method.getParameterAnnotations(j+startIndex); >+ if (paramAnnotations != null) { >+ for (int i = 0; i < paramAnnotations.length; i++) { >+ char[] annotationTypeName = paramAnnotations[i].getTypeName(); >+ if (annotationTypeName[0] != Util.C_RESOLVED) >+ continue; >+ char[][] typeName = CharOperation.splitOn('/', annotationTypeName, 1, annotationTypeName.length-1); // cut of leading 'L' and trailing ';' >+ if (CharOperation.equals(typeName, nonNullAnnotationName)) { >+ if (methodBinding.parameterNonNullness == null) >+ methodBinding.parameterNonNullness = new Boolean[numVisibleParams]; >+ methodBinding.parameterNonNullness[j] = Boolean.TRUE; >+ explicitNullness = true; >+ break; >+ } else if (CharOperation.equals(typeName, nullableAnnotationName)) { >+ if (methodBinding.parameterNonNullness == null) >+ methodBinding.parameterNonNullness = new Boolean[numVisibleParams]; >+ methodBinding.parameterNonNullness[j] = Boolean.FALSE; >+ explicitNullness = true; >+ break; >+ } >+ } >+ } >+ } >+ if (!explicitNullness && currentDefault == NONNULL_BY_DEFAULT) { >+ if (methodBinding.parameterNonNullness == null) >+ methodBinding.parameterNonNullness = new Boolean[numVisibleParams]; >+ methodBinding.parameterNonNullness[j] = Boolean.TRUE; >+ } >+ } >+ } >+} >+void scanTypeForNullDefaultAnnotation(IBinaryType binaryType) { >+ char[][] nonNullByDefaultAnnotationName = this.environment.getNonNullByDefaultAnnotationName(); >+ if (nonNullByDefaultAnnotationName == null) >+ return; // not well-configured to use null annotations >+ >+ IBinaryAnnotation[] annotations = binaryType.getAnnotations(); >+ if (annotations != null) { >+ long annotationBit = 0L; >+ int nullness = NO_NULL_DEFAULT; >+ int length = annotations.length; >+ for (int i = 0; i < length; i++) { >+ char[] annotationTypeName = annotations[i].getTypeName(); >+ if (annotationTypeName[0] != Util.C_RESOLVED) >+ continue; >+ char[][] typeName = CharOperation.splitOn('/', annotationTypeName, 1, annotationTypeName.length-1); // cut of leading 'L' and trailing ';' >+ if (CharOperation.equals(typeName, nonNullByDefaultAnnotationName)) { >+ IBinaryElementValuePair[] elementValuePairs = annotations[i].getElementValuePairs(); >+ if (elementValuePairs != null && elementValuePairs.length == 1) { >+ Object value = elementValuePairs[0].getValue(); >+ if (value instanceof BooleanConstant >+ && !((BooleanConstant)value).booleanValue()) >+ { >+ // parameter is 'false': this means we cancel defaults from outer scopes: >+ annotationBit = TagBits.AnnotationNullUnspecifiedByDefault; >+ nullness = NULL_UNSPECIFIED_BY_DEFAULT; >+ break; >+ } >+ } >+ annotationBit = TagBits.AnnotationNonNullByDefault; >+ nullness = NONNULL_BY_DEFAULT; >+ break; >+ } >+ } >+ if (annotationBit != 0L) { >+ this.tagBits |= annotationBit; >+ if (CharOperation.equals(this.sourceName(), TypeConstants.PACKAGE_INFO_NAME)) >+ this.getPackage().defaultNullness = nullness; >+ } else { >+ switch (this.getPackage().defaultNullness) { >+ case NONNULL_BY_DEFAULT : >+ this.tagBits |= TagBits.AnnotationNonNullByDefault; >+ break; >+ case NULL_UNSPECIFIED_BY_DEFAULT : >+ this.tagBits |= TagBits.AnnotationNullUnspecifiedByDefault; >+ break; >+ } >+ } >+ } >+} >+ > /* Answer the receiver's superclass... null if the receiver is Object or an interface. > * > * NOTE: superclass of a binary type is resolved when needed >@@ -1139,8 +1302,22 @@ > // finish resolving the type > this.superclass = (ReferenceBinding) resolveType(this.superclass, this.environment, true /* raw conversion */); > this.tagBits &= ~TagBits.HasUnresolvedSuperclass; >- if (this.superclass.problemId() == ProblemReasons.NotFound) >+ if (this.superclass.problemId() == ProblemReasons.NotFound) { > this.tagBits |= TagBits.HierarchyHasProblems; // propagate type inconsistency >+ } else { >+ // make super-type resolving recursive for propagating typeBits downwards >+ boolean wasToleratingMissingTypeProcessingAnnotations = this.environment.mayTolerateMissingType; >+ this.environment.mayTolerateMissingType = true; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=360164 >+ try { >+ this.superclass.superclass(); >+ this.superclass.superInterfaces(); >+ } finally { >+ this.environment.mayTolerateMissingType = wasToleratingMissingTypeProcessingAnnotations; >+ } >+ } >+ this.typeBits |= (this.superclass.typeBits & TypeIds.InheritableBits); >+ if ((this.typeBits & (TypeIds.BitAutoCloseable|TypeIds.BitCloseable)) != 0) // avoid the side-effects of hasTypeBit()! >+ this.typeBits |= applyCloseableWhitelists(); > return this.superclass; > } > // NOTE: superInterfaces of binary types are resolved when needed >@@ -1150,8 +1327,20 @@ > > for (int i = this.superInterfaces.length; --i >= 0;) { > this.superInterfaces[i] = (ReferenceBinding) resolveType(this.superInterfaces[i], this.environment, true /* raw conversion */); >- if (this.superInterfaces[i].problemId() == ProblemReasons.NotFound) >+ if (this.superInterfaces[i].problemId() == ProblemReasons.NotFound) { > this.tagBits |= TagBits.HierarchyHasProblems; // propagate type inconsistency >+ } else { >+ // make super-type resolving recursive for propagating typeBits downwards >+ boolean wasToleratingMissingTypeProcessingAnnotations = this.environment.mayTolerateMissingType; >+ this.environment.mayTolerateMissingType = true; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=360164 >+ try { >+ this.superInterfaces[i].superclass(); >+ this.superInterfaces[i].superInterfaces(); >+ } finally { >+ this.environment.mayTolerateMissingType = wasToleratingMissingTypeProcessingAnnotations; >+ } >+ } >+ this.typeBits |= (this.superInterfaces[i].typeBits & TypeIds.InheritableBits); > } > this.tagBits &= ~TagBits.HasUnresolvedSuperinterfaces; > return this.superInterfaces; >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Binding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Binding.java >index d0e769e..5725ea3 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Binding.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Binding.java >@@ -7,6 +7,8 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contribution for >+ * bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.lookup; > >@@ -48,6 +50,11 @@ > public static final MethodBinding[] UNINITIALIZED_METHODS = new MethodBinding[0]; > public static final ReferenceBinding[] UNINITIALIZED_REFERENCE_TYPES = new ReferenceBinding[0]; > >+ // Nullness defaults: >+ public static final int NO_NULL_DEFAULT = 0; >+ public static final int NULL_UNSPECIFIED_BY_DEFAULT = 1; >+ public static final int NONNULL_BY_DEFAULT = 2; >+ > /* > * Answer the receiver's binding type from Binding.BindingID. > */ >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java >index b3613a7..699f630 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,13 +7,26 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contributions for >+ * bug 349326 - [1.7] new warning for missing try-with-resources >+ * bug 359334 - Analysis for resource leak warnings does not consider exceptions as method exit points >+ * bug 358903 - Filter practically unimportant resource leak warnings >+ * bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK >+ * bug 370639 - [compiler][resource] restore the default for resource leak warnings > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.lookup; >+ >+import java.util.ArrayList; >+import java.util.HashSet; >+import java.util.List; >+import java.util.Set; > > import org.eclipse.jdt.core.compiler.CharOperation; > import org.eclipse.jdt.internal.compiler.ast.*; > import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; > import org.eclipse.jdt.internal.compiler.codegen.CodeStream; >+import org.eclipse.jdt.internal.compiler.flow.FlowContext; >+import org.eclipse.jdt.internal.compiler.flow.FlowInfo; > import org.eclipse.jdt.internal.compiler.impl.Constant; > import org.eclipse.jdt.internal.compiler.problem.ProblemReporter; > >@@ -957,4 +970,152 @@ > } > } > } >+ >+private List trackingVariables; // can be null if no resources are tracked >+/** Used only during analyseCode and only for checking if a resource was closed in a finallyBlock. */ >+public FlowInfo finallyInfo; >+/** >+ * Register a tracking variable and compute its id. >+ */ >+public int registerTrackingVariable(FakedTrackingVariable fakedTrackingVariable) { >+ if (this.trackingVariables == null) >+ this.trackingVariables = new ArrayList(3); >+ this.trackingVariables.add(fakedTrackingVariable); >+ MethodScope outerMethodScope = outerMostMethodScope(); >+ return outerMethodScope.analysisIndex++; >+} >+/** When are no longer interested in this tracking variable - remove it. */ >+public void removeTrackingVar(FakedTrackingVariable trackingVariable) { >+ if (trackingVariable.innerTracker != null) { >+ removeTrackingVar(trackingVariable.innerTracker); >+ trackingVariable.innerTracker = null; >+ } >+ if (this.trackingVariables != null) >+ if (this.trackingVariables.remove(trackingVariable)) >+ return; >+ if (this.parent instanceof BlockScope) >+ ((BlockScope)this.parent).removeTrackingVar(trackingVariable); >+} >+/** Unregister a wrapper resource without affecting its inner. */ >+public void pruneWrapperTrackingVar(FakedTrackingVariable trackingVariable) { >+ this.trackingVariables.remove(trackingVariable); >+} >+/** >+ * At the end of a block check the closing-status of all tracked closeables that are declared in this block. >+ * Also invoked when entering unreachable code. >+ */ >+public void checkUnclosedCloseables(FlowInfo flowInfo, FlowContext flowContext, ASTNode location, BlockScope locationScope) { >+ if (!compilerOptions().analyseResourceLeaks) return; >+ if (this.trackingVariables == null) { >+ // at a method return we also consider enclosing scopes >+ if (location != null && this.parent instanceof BlockScope) >+ ((BlockScope) this.parent).checkUnclosedCloseables(flowInfo, flowContext, location, locationScope); >+ return; >+ } >+ if (location != null && flowInfo.reachMode() != 0) return; >+ >+ FakedTrackingVariable returnVar = (location instanceof ReturnStatement) ? >+ FakedTrackingVariable.getCloseTrackingVariable(((ReturnStatement)location).expression) : null; >+ >+ Set varSet = new HashSet(this.trackingVariables); >+ FakedTrackingVariable trackingVar; >+ // pick one outer-most variable from the set at a time >+ while ((trackingVar = FakedTrackingVariable.pickVarForReporting(varSet, this, location != null)) != null) { >+ >+ if (returnVar != null && trackingVar.isResourceBeingReturned(returnVar)) { >+ continue; >+ } >+ >+ if (location != null && trackingVar.hasDefinitelyNoResource(flowInfo)) { >+ continue; // reporting against a specific location, there is no resource at this flow, don't complain >+ } >+ >+ if (location != null && flowContext != null && flowContext.recordExitAgainstResource(this, flowInfo, trackingVar, location)) { >+ continue; // handled by the flow context >+ } >+ >+ // compute the most specific null status for this resource, >+ int status = trackingVar.findMostSpecificStatus(flowInfo, this, locationScope); >+ >+ if (status == FlowInfo.NULL) { >+ // definitely unclosed: highest priority >+ reportResourceLeak(trackingVar, location, status); >+ continue; >+ } >+ if (location == null) // at end of block and not definitely unclosed >+ { >+ // problems at specific locations: medium priority >+ if (trackingVar.reportRecordedErrors(this, status)) // ... report previously recorded errors >+ continue; >+ } >+ if (status == FlowInfo.POTENTIALLY_NULL) { >+ // potentially unclosed: lower priority >+ reportResourceLeak(trackingVar, location, status); >+ } else if (status == FlowInfo.NON_NULL) { >+ // properly closed but not managed by t-w-r: lowest priority >+ if (environment().globalOptions.complianceLevel >= ClassFileConstants.JDK1_7) >+ trackingVar.reportExplicitClosing(problemReporter()); >+ } >+ } >+ if (location == null) { >+ // when leaving this block dispose off all tracking variables: >+ for (int i=0; i<this.localIndex; i++) >+ this.locals[i].closeTracker = null; >+ this.trackingVariables = null; >+ } else { >+ int size = this.trackingVariables.size(); >+ for (int i=0; i<size; i++) { >+ FakedTrackingVariable tracker = (FakedTrackingVariable) this.trackingVariables.get(0); >+ tracker.resetReportingBits(); >+ } >+ } >+} >+ >+private void reportResourceLeak(FakedTrackingVariable trackingVar, ASTNode location, int nullStatus) { >+ if (location != null) >+ trackingVar.recordErrorLocation(location, nullStatus); >+ else >+ trackingVar.reportError(problemReporter(), null, nullStatus); >+} >+ >+/** >+ * If one branch of an if-else closes any AutoCloseable resource, and if the same >+ * resource is known to be null on the other branch mark it as closed, too, >+ * so that merging both branches indicates that the resource is always closed. >+ * Example: >+ * FileReader fr1 = null; >+ * try {\n" + >+ * fr1 = new FileReader(someFile);" + >+ * fr1.read(buf);\n" + >+ * } finally {\n" + >+ * if (fr1 != null)\n" + >+ * try {\n" + >+ * fr1.close();\n" + >+ * } catch (IOException e) { >+ * // do nothing >+ * } >+ * // after this if statement fr1 is definitely not leaked >+ * } >+ */ >+public void correlateTrackingVarsIfElse(FlowInfo thenFlowInfo, FlowInfo elseFlowInfo) { >+ if (this.trackingVariables != null) { >+ for (int i=0; i<this.trackingVariables.size(); i++) { >+ FakedTrackingVariable trackingVar = (FakedTrackingVariable) this.trackingVariables.get(i); >+ if (trackingVar.originalBinding == null) >+ continue; >+ if ( thenFlowInfo.isDefinitelyNonNull(trackingVar.binding) // closed in then branch >+ && elseFlowInfo.isDefinitelyNull(trackingVar.originalBinding)) // null in else branch >+ { >+ elseFlowInfo.markAsDefinitelyNonNull(trackingVar.binding); // -> always closed >+ } >+ else if ( elseFlowInfo.isDefinitelyNonNull(trackingVar.binding) // closed in else branch >+ && thenFlowInfo.isDefinitelyNull(trackingVar.originalBinding)) // null in then branch >+ { >+ thenFlowInfo.markAsDefinitelyNonNull(trackingVar.binding); // -> always closed >+ } >+ } >+ } >+ if (this.parent instanceof BlockScope) >+ ((BlockScope) this.parent).correlateTrackingVarsIfElse(thenFlowInfo, elseFlowInfo); >+} > } >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java >index eb865be..8778c6b 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -11,6 +11,8 @@ > * Bug 328281 - visibility leaks not detected when analyzing unused field in private class > * Bug 300576 - NPE Computing type hierarchy when compliance doesn't match libraries > * Bug 354536 - compiling package-info.java still depends on the order of compilation units >+ * Bug 349326 - [1.7] new warning for missing try-with-resources >+ * Bug 358903 - Filter practically unimportant resource leak warnings > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.lookup; > >@@ -908,6 +910,10 @@ > } else { > // only want to reach here when no errors are reported > sourceType.superclass = superclass; >+ sourceType.typeBits |= (superclass.typeBits & TypeIds.InheritableBits); >+ // further analysis against white lists for the unlikely case we are compiling java.io.*: >+ if ((sourceType.typeBits & (TypeIds.BitAutoCloseable|TypeIds.BitCloseable)) != 0) >+ sourceType.typeBits |= sourceType.applyCloseableWhitelists(); > return true; > } > } >@@ -1023,6 +1029,7 @@ > noProblems &= superInterfaceRef.resolvedType.isValidBinding(); > } > // only want to reach here when no errors are reported >+ sourceType.typeBits |= (superInterface.typeBits & TypeIds.InheritableBits); > interfaceBindings[count++] = superInterface; > } > // hold onto all correctly resolved superinterfaces >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java >index 32ccfd8..567c934 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java >@@ -25,6 +25,7 @@ > public char[][] currentPackageName; > public PackageBinding fPackage; > public ImportBinding[] imports; >+ public int importPtr; > public HashtableOfObject typeOrPackageCache; // used in Scope.getTypeOrPackage() > > public SourceTypeBinding[] topLevelTypes; >@@ -37,6 +38,8 @@ > > HashtableOfType constantPoolNameUsage; > private int captureID = 1; >+ >+ private ImportBinding[] tempImports; // to keep a record of resolved imports while traversing all in faultInImports() > > public CompilationUnitScope(CompilationUnitDeclaration unit, LookupEnvironment environment) { > super(COMPILATION_UNIT_SCOPE, null); >@@ -328,10 +331,10 @@ > break; > } > } >- ImportBinding[] resolvedImports = new ImportBinding[numberOfImports]; >- resolvedImports[0] = getDefaultImports()[0]; >- int index = 1; >- >+ this.tempImports = new ImportBinding[numberOfImports]; >+ this.tempImports[0] = getDefaultImports()[0]; >+ this.importPtr = 1; >+ > // keep static imports with normal imports until there is a reason to split them up > // on demand imports continue to be packages & types. need to check on demand type imports for fields/methods > // single imports change from being just types to types or fields >@@ -340,8 +343,8 @@ > char[][] compoundName = importReference.tokens; > > // skip duplicates or imports of the current package >- for (int j = 0; j < index; j++) { >- ImportBinding resolved = resolvedImports[j]; >+ for (int j = 0; j < this.importPtr; j++) { >+ ImportBinding resolved = this.tempImports[j]; > if (resolved.onDemand == ((importReference.bits & ASTNode.OnDemand) != 0) && resolved.isStatic() == importReference.isStatic()) { > if (CharOperation.equals(compoundName, resolved.compoundName)) { > problemReporter().unusedImport(importReference); // since skipped, must be reported now >@@ -364,7 +367,7 @@ > problemReporter().cannotImportPackage(importReference); > continue nextImport; > } >- resolvedImports[index++] = new ImportBinding(compoundName, true, importBinding, importReference); >+ recordImportBinding(new ImportBinding(compoundName, true, importBinding, importReference)); > } else { > Binding importBinding = findSingleImport(compoundName, Binding.TYPE | Binding.FIELD | Binding.METHOD, importReference.isStatic()); > if (!importBinding.isValidBinding()) { >@@ -379,81 +382,28 @@ > problemReporter().cannotImportPackage(importReference); > continue nextImport; > } >- ReferenceBinding conflictingType = null; >- if (importBinding instanceof MethodBinding) { >- conflictingType = (ReferenceBinding) getType(compoundName, compoundName.length); >- if (!conflictingType.isValidBinding() || (importReference.isStatic() && !conflictingType.isStatic())) >- conflictingType = null; >- } >- // collisions between an imported static field & a type should be checked according to spec... but currently not by javac >- if (importBinding instanceof ReferenceBinding || conflictingType != null) { >- ReferenceBinding referenceBinding = conflictingType == null ? (ReferenceBinding) importBinding : conflictingType; >- ReferenceBinding typeToCheck = referenceBinding.problemId() == ProblemReasons.Ambiguous >- ? ((ProblemReferenceBinding) referenceBinding).closestMatch >- : referenceBinding; >- if (importReference.isTypeUseDeprecated(typeToCheck, this)) >- problemReporter().deprecatedType(typeToCheck, importReference); >- >- ReferenceBinding existingType = typesBySimpleNames.get(compoundName[compoundName.length - 1]); >- if (existingType != null) { >- // duplicate test above should have caught this case, but make sure >- if (existingType == referenceBinding) { >- // https://bugs.eclipse.org/bugs/show_bug.cgi?id=302865 >- // Check all resolved imports to see if this import qualifies as a duplicate >- for (int j = 0; j < index; j++) { >- ImportBinding resolved = resolvedImports[j]; >- if (resolved instanceof ImportConflictBinding) { >- ImportConflictBinding importConflictBinding = (ImportConflictBinding) resolved; >- if (importConflictBinding.conflictingTypeBinding == referenceBinding) { >- if (!importReference.isStatic()) { >- // resolved is implicitly static >- problemReporter().duplicateImport(importReference); >- resolvedImports[index++] = new ImportBinding(compoundName, false, importBinding, importReference); >- } >- } >- } else if (resolved.resolvedImport == referenceBinding) { >- if (importReference.isStatic() != resolved.isStatic()) { >- problemReporter().duplicateImport(importReference); >- resolvedImports[index++] = new ImportBinding(compoundName, false, importBinding, importReference); >- } >- } >- } >- continue nextImport; >- } >- // either the type collides with a top level type or another imported type >- for (int j = 0, length = this.topLevelTypes.length; j < length; j++) { >- if (CharOperation.equals(this.topLevelTypes[j].sourceName, existingType.sourceName)) { >- problemReporter().conflictingImport(importReference); >- continue nextImport; >- } >- } >- problemReporter().duplicateImport(importReference); >- continue nextImport; >- } >- typesBySimpleNames.put(compoundName[compoundName.length - 1], referenceBinding); >- } else if (importBinding instanceof FieldBinding) { >- for (int j = 0; j < index; j++) { >- ImportBinding resolved = resolvedImports[j]; >- // find other static fields with the same name >- if (resolved.isStatic() && resolved.resolvedImport instanceof FieldBinding && importBinding != resolved.resolvedImport) { >- if (CharOperation.equals(compoundName[compoundName.length - 1], resolved.compoundName[resolved.compoundName.length - 1])) { >- problemReporter().duplicateImport(importReference); >- continue nextImport; >- } >- } >+ // all the code here which checks for valid bindings have been moved to the method >+ // checkAndRecordImportBinding() since bug 361327 >+ if(checkAndRecordImportBinding(importBinding, typesBySimpleNames, importReference, compoundName) == -1) >+ continue nextImport; >+ if (importReference.isStatic()) { >+ // look for more static bindings being imported by single static import(bug 361327). >+ // findSingleImport() finds fields first, followed by method and then type >+ // So if a type is found, no fields and methods are available anyway >+ // similarly when method is found, type may be available but no field available for sure >+ if (importBinding.kind() == Binding.FIELD) { >+ checkMoreStaticBindings(compoundName, typesBySimpleNames, Binding.TYPE | Binding.METHOD, importReference); >+ } else if (importBinding.kind() == Binding.METHOD) { >+ checkMoreStaticBindings(compoundName, typesBySimpleNames, Binding.TYPE, importReference); > } > } >- resolvedImports[index++] = conflictingType == null >- ? new ImportBinding(compoundName, false, importBinding, importReference) >- : new ImportConflictBinding(compoundName, importBinding, conflictingType, importReference); > } > } > > // shrink resolvedImports... only happens if an error was reported >- if (resolvedImports.length > index) >- System.arraycopy(resolvedImports, 0, resolvedImports = new ImportBinding[index], 0, index); >- this.imports = resolvedImports; >- >+ if (this.tempImports.length > this.importPtr) >+ System.arraycopy(this.tempImports, 0, this.tempImports = new ImportBinding[this.importPtr], 0, this.importPtr); >+ this.imports = this.tempImports; > int length = this.imports.length; > this.typeOrPackageCache = new HashtableOfObject(length); > for (int i = 0; i < length; i++) { >@@ -840,4 +790,129 @@ > for (int i = 0, length = this.topLevelTypes.length; i < length; i++) > this.topLevelTypes[i].verifyMethods(verifier); > } >+private void recordImportBinding(ImportBinding bindingToAdd) { >+ if (this.tempImports.length == this.importPtr) { >+ System.arraycopy(this.tempImports, 0, (this.tempImports = new ImportBinding[this.importPtr + 1]), 0, this.importPtr); >+ } >+ this.tempImports[this.importPtr++] = bindingToAdd; >+} >+/** >+ * Checks additional bindings (methods or types) imported from a single static import. >+ * Method is tried first, followed by type. If found, records them. >+ * If in the process, import is flagged as duplicate, -1 is returned. >+ * @param compoundName >+ * @param typesBySimpleNames >+ * @param mask >+ * @param importReference >+ */ >+private void checkMoreStaticBindings( >+ char[][] compoundName, >+ HashtableOfType typesBySimpleNames, >+ int mask, >+ ImportReference importReference) { >+ Binding importBinding = findSingleStaticImport(compoundName, mask); >+ if (!importBinding.isValidBinding()) { >+ // only continue if the same kind's ambiguous binding is returned >+ // may have found an ambiguous type when looking for field or method. Don't continue in that case >+ if (importBinding.problemId() == ProblemReasons.Ambiguous) { >+ // keep it unless a duplicate can be found below >+ checkAndRecordImportBinding(importBinding, typesBySimpleNames, importReference, compoundName); >+ } >+ } else { >+ checkAndRecordImportBinding(importBinding, typesBySimpleNames, importReference, compoundName); >+ } >+ if (((mask & Binding.METHOD) != 0) && (importBinding.kind() == Binding.METHOD)) { >+ // found method >+ // type is left to be looked for >+ // reset METHOD bit to enable lookup for only type >+ mask &= ~Binding.METHOD; >+ // now search for a type binding >+ checkMoreStaticBindings(compoundName, typesBySimpleNames, mask, importReference); >+ } >+} >+/** >+ * Checks for duplicates. If all ok, records the importBinding >+ * returns -1 when this import is flagged as duplicate. >+ * @param importBinding >+ * @param typesBySimpleNames >+ * @param importReference >+ * @param compoundName >+ * @return -1 when this import is flagged as duplicate, importPtr otherwise. >+ */ >+private int checkAndRecordImportBinding( >+ Binding importBinding, >+ HashtableOfType typesBySimpleNames, >+ ImportReference importReference, >+ char[][] compoundName) { >+ ReferenceBinding conflictingType = null; >+ if (importBinding instanceof MethodBinding) { >+ conflictingType = (ReferenceBinding) getType(compoundName, compoundName.length); >+ if (!conflictingType.isValidBinding() || (importReference.isStatic() && !conflictingType.isStatic())) >+ conflictingType = null; >+ } >+ // collisions between an imported static field & a type should be checked according to spec... but currently not by javac >+ if (importBinding instanceof ReferenceBinding || conflictingType != null) { >+ ReferenceBinding referenceBinding = conflictingType == null ? (ReferenceBinding) importBinding : conflictingType; >+ ReferenceBinding typeToCheck = referenceBinding.problemId() == ProblemReasons.Ambiguous >+ ? ((ProblemReferenceBinding) referenceBinding).closestMatch >+ : referenceBinding; >+ if (importReference.isTypeUseDeprecated(typeToCheck, this)) >+ problemReporter().deprecatedType(typeToCheck, importReference); >+ >+ ReferenceBinding existingType = typesBySimpleNames.get(compoundName[compoundName.length - 1]); >+ if (existingType != null) { >+ // duplicate test above should have caught this case, but make sure >+ if (existingType == referenceBinding) { >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=302865 >+ // Check all resolved imports to see if this import qualifies as a duplicate >+ for (int j = 0; j < this.importPtr; j++) { >+ ImportBinding resolved = this.tempImports[j]; >+ if (resolved instanceof ImportConflictBinding) { >+ ImportConflictBinding importConflictBinding = (ImportConflictBinding) resolved; >+ if (importConflictBinding.conflictingTypeBinding == referenceBinding) { >+ if (!importReference.isStatic()) { >+ // resolved is implicitly static >+ problemReporter().duplicateImport(importReference); >+ recordImportBinding(new ImportBinding(compoundName, false, importBinding, importReference)); >+ } >+ } >+ } else if (resolved.resolvedImport == referenceBinding) { >+ if (importReference.isStatic() != resolved.isStatic()) { >+ problemReporter().duplicateImport(importReference); >+ recordImportBinding(new ImportBinding(compoundName, false, importBinding, importReference)); >+ } >+ } >+ } >+ return -1; >+ } >+ // either the type collides with a top level type or another imported type >+ for (int j = 0, length = this.topLevelTypes.length; j < length; j++) { >+ if (CharOperation.equals(this.topLevelTypes[j].sourceName, existingType.sourceName)) { >+ problemReporter().conflictingImport(importReference); >+ return -1; >+ } >+ } >+ problemReporter().duplicateImport(importReference); >+ return -1; >+ } >+ typesBySimpleNames.put(compoundName[compoundName.length - 1], referenceBinding); >+ } else if (importBinding instanceof FieldBinding) { >+ for (int j = 0; j < this.importPtr; j++) { >+ ImportBinding resolved = this.tempImports[j]; >+ // find other static fields with the same name >+ if (resolved.isStatic() && resolved.resolvedImport instanceof FieldBinding && importBinding != resolved.resolvedImport) { >+ if (CharOperation.equals(compoundName[compoundName.length - 1], resolved.compoundName[resolved.compoundName.length - 1])) { >+ problemReporter().duplicateImport(importReference); >+ return -1; >+ } >+ } >+ } >+ } >+ if (conflictingType == null) { >+ recordImportBinding(new ImportBinding(compoundName, false, importBinding, importReference)); >+ } else { >+ recordImportBinding(new ImportConflictBinding(compoundName, importBinding, conflictingType, importReference)); >+ } >+ return this.importPtr; >+} > } >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalTypeBinding.java >index 3cf3183..359c707 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalTypeBinding.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalTypeBinding.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,12 +7,14 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contribution for bug 365662 - [compiler][null] warn on contradictory and redundant null annotations > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.lookup; > > import org.eclipse.jdt.core.compiler.CharOperation; > import org.eclipse.jdt.internal.compiler.ast.ASTNode; > import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; >+import org.eclipse.jdt.internal.compiler.ast.Annotation; > import org.eclipse.jdt.internal.compiler.ast.CaseStatement; > import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; > import org.eclipse.jdt.internal.compiler.ast.TypeReference; >@@ -85,6 +87,17 @@ > return this.superclass; // default answer > } > >+protected void checkRedundantNullnessDefaultRecurse(ASTNode location, Annotation[] annotations, long annotationTagBits) { >+ long outerDefault = this.enclosingMethod != null ? this.enclosingMethod.tagBits & ((TagBits.AnnotationNonNullByDefault|TagBits.AnnotationNullUnspecifiedByDefault)) : 0; >+ if (outerDefault != 0) { >+ if (outerDefault == annotationTagBits) { >+ this.scope.problemReporter().nullDefaultAnnotationIsRedundant(location, annotations, this.enclosingMethod); >+ } >+ return; >+ } >+ super.checkRedundantNullnessDefaultRecurse(location, annotations, annotationTagBits); >+} >+ > public char[] computeUniqueKey(boolean isLeaf) { > char[] outerKey = outermostEnclosingType().computeUniqueKey(isLeaf); > int semicolon = CharOperation.lastIndexOf(';', outerKey); >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalVariableBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalVariableBinding.java >index d0bd849..5f6ea20 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalVariableBinding.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalVariableBinding.java >@@ -4,10 +4,13 @@ > * 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: > * IBM Corporation - initial API and implementation >- * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 185682 - Increment/decrement operators mark local variables as read >+ * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for >+ * bug 185682 - Increment/decrement operators mark local variables as read >+ * bug 349326 - [1.7] new warning for missing try-with-resources >+ * bug 186342 - [compiler][null] Using annotations for null checking > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.lookup; > >@@ -15,6 +18,7 @@ > import org.eclipse.jdt.internal.compiler.ast.ASTNode; > import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; > import org.eclipse.jdt.internal.compiler.ast.Annotation; >+import org.eclipse.jdt.internal.compiler.ast.FakedTrackingVariable; > import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration; > import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; > import org.eclipse.jdt.internal.compiler.impl.Constant; >@@ -34,6 +38,8 @@ > > public int[] initializationPCs; > public int initializationCount = 0; >+ >+ public FakedTrackingVariable closeTracker; // track closing of instances of type AutoCloseable, maybe null > > // for synthetic local variables > // if declaration slot is not positionned, the variable will not be listed in attribute >@@ -153,7 +159,7 @@ > annotations = new AnnotationBinding[length]; > for (int i = 0; i < length; i++) > annotations[i] = new AnnotationBinding(annotationNodes[i]); >- setAnnotations(annotations); >+ setAnnotations(annotations, this.declaringScope); > } > } > } >@@ -207,10 +213,12 @@ > this.initializationCount++; > } > >- public void setAnnotations(AnnotationBinding[] annotations) { >- if (this.declaringScope == null) return; >- >- SourceTypeBinding sourceType = this.declaringScope.enclosingSourceType(); >+ public void setAnnotations(AnnotationBinding[] annotations, Scope scope) { >+ // note: we don's use this.declaringScope because we might be called before Scope.addLocalVariable(this) >+ // which is where this.declaringScope is set. >+ if (scope == null) >+ return; >+ SourceTypeBinding sourceType = scope.enclosingSourceType(); > if (sourceType != null) > sourceType.storeAnnotations(this, annotations); > } >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java >index 84d3e74..7489fbc 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,7 +7,10 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >- * Stephan Herrmann - contribution for bug 337868 - [compiler][model] incomplete support for package-info.java when using SearchableEnvironment >+ * Stephan Herrmann - contributions for >+ * bug 337868 - [compiler][model] incomplete support for package-info.java when using SearchableEnvironment >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.lookup; > >@@ -74,6 +77,11 @@ > private ArrayList missingTypes; > Set typesBeingConnected; > public boolean isProcessingAnnotations = false; >+ public boolean mayTolerateMissingType = false; >+ >+ PackageBinding nullableAnnotationPackage; // the package supposed to contain the Nullable annotation type >+ PackageBinding nonnullAnnotationPackage; // the package supposed to contain the NonNull annotation type >+ PackageBinding nonnullByDefaultAnnotationPackage; // the package supposed to contain the NonNullByDefault annotation type > > final static int BUILD_FIELDS_AND_METHODS = 4; > final static int BUILD_TYPE_HIERARCHY = 1; >@@ -82,6 +90,7 @@ > > static final ProblemPackageBinding TheNotFoundPackage = new ProblemPackageBinding(CharOperation.NO_CHAR, NotFound); > static final ProblemReferenceBinding TheNotFoundType = new ProblemReferenceBinding(CharOperation.NO_CHAR_CHAR, null, NotFound); >+ > > public LookupEnvironment(ITypeRequestor typeRequestor, CompilerOptions globalOptions, ProblemReporter problemReporter, INameEnvironment nameEnvironment) { > this.typeRequestor = typeRequestor; >@@ -1072,6 +1081,18 @@ > return packageBinding.getType0(compoundName[compoundName.length - 1]); > } > >+public char[][] getNullableAnnotationName() { >+ return this.globalOptions.nullableAnnotationName; >+} >+ >+public char[][] getNonNullAnnotationName() { >+ return this.globalOptions.nonNullAnnotationName; >+} >+ >+public char[][] getNonNullByDefaultAnnotationName() { >+ return this.globalOptions.nonNullByDefaultAnnotationName; >+} >+ > /* Answer the top level package named name if it exists in the cache. > * Answer theNotFoundPackage if it could not be resolved the first time > * it was looked up, otherwise answer null. >@@ -1194,7 +1215,13 @@ > packageBinding.addType(binding); > } else if (binding == TheNotFoundType) { > // report the missing class file first >- this.problemReporter.isClassPathCorrect(compoundName, this.unitBeingCompleted, this.missingClassFileLocation); >+ if (!wasMissingType) { >+ /* Since missing types have been already been complained against while producing binaries, there is no class path >+ * misconfiguration now that did not also exist in some equivalent form while producing the class files which encode >+ * these missing types. So no need to bark again. Note that wasMissingType == true signals a type referenced in a .class >+ * file which could not be found when the binary was produced. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=364450 */ >+ this.problemReporter.isClassPathCorrect(compoundName, this.unitBeingCompleted, this.missingClassFileLocation); >+ } > // create a proxy for the missing BinaryType > binding = createMissingType(null, compoundName); > } else if (!isParameterized) { >@@ -1453,6 +1480,7 @@ > this.unitBeingCompleted = null; // in case AbortException occurred > > this.classFilePool.reset(); >+ > // name environment has a longer life cycle, and must be reset in > // the code which created it. > } >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java >index 33c56ef..ce25e57 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java >@@ -1,12 +1,18 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contributions for >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 367203 - [compiler][null] detect assigning null to nonnull argument >+ * bug 365519 - editorial cleanup after bug 186342 and bug 365387 >+ * bug 365662 - [compiler][null] warn on contradictory and redundant null annotations >+ * bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.lookup; > >@@ -33,6 +39,9 @@ > public TypeVariableBinding[] typeVariables = Binding.NO_TYPE_VARIABLES; > char[] signature; > public long tagBits; >+ >+ /** Store nullness information from annotation (incl. applicable default). */ >+ public Boolean[] parameterNonNullness; // TRUE means @NonNull declared, FALSE means @Nullable declared, null means nothing declared > > protected MethodBinding() { > // for creating problem or synthetic method >@@ -439,6 +448,40 @@ > return this.selector; > } > >+/** >+ * After method verifier has finished, fill in missing @NonNull specification from the applicable default. >+ */ >+protected void fillInDefaultNonNullness() { >+ if (this.parameterNonNullness == null) >+ this.parameterNonNullness = new Boolean[this.parameters.length]; >+ AbstractMethodDeclaration sourceMethod = sourceMethod(); >+ boolean added = false; >+ int length = this.parameterNonNullness.length; >+ for (int i = 0; i < length; i++) { >+ if (this.parameters[i].isBaseType()) >+ continue; >+ if (this.parameterNonNullness[i] == null) { >+ added = true; >+ this.parameterNonNullness[i] = Boolean.TRUE; >+ if (sourceMethod != null) { >+ sourceMethod.arguments[i].binding.tagBits |= TagBits.AnnotationNonNull; >+ } >+ } else if (this.parameterNonNullness[i].booleanValue()) { >+ sourceMethod.scope.problemReporter().nullAnnotationIsRedundant(sourceMethod, i); >+ } >+ } >+ if (added) >+ this.tagBits |= TagBits.HasParameterAnnotations; >+ if ( this.returnType != null >+ && !this.returnType.isBaseType() >+ && (this.tagBits & (TagBits.AnnotationNonNull|TagBits.AnnotationNullable)) == 0) >+ { >+ this.tagBits |= TagBits.AnnotationNonNull; >+ } else if ((this.tagBits & TagBits.AnnotationNonNull) != 0) { >+ sourceMethod.scope.problemReporter().nullAnnotationIsRedundant(sourceMethod, -1/*signifies method return*/); >+ } >+} >+ > public MethodBinding findOriginalInheritedMethod(MethodBinding inheritedMethod) { > MethodBinding inheritedOriginal = inheritedMethod.original(); > TypeBinding superType = this.declaringClass.findSuperTypeOriginatingFrom(inheritedOriginal.declaringClass); >@@ -524,6 +567,13 @@ > AbstractMethodDeclaration methodDecl = typeDecl.declarationOf(originalMethod); > if (methodDecl != null) > ASTNode.resolveAnnotations(methodDecl.scope, methodDecl.annotations, originalMethod); >+ long nullDefaultBits = this.tagBits & (TagBits.AnnotationNonNullByDefault|TagBits.AnnotationNullUnspecifiedByDefault); >+ if (nullDefaultBits != 0 && this.declaringClass instanceof SourceTypeBinding) { >+ SourceTypeBinding declaringSourceType = (SourceTypeBinding) this.declaringClass; >+ if (declaringSourceType.checkRedundantNullnessDefaultOne(methodDecl, methodDecl.annotations, nullDefaultBits)) { >+ declaringSourceType.checkRedundantNullnessDefaultRecurse(methodDecl, methodDecl.annotations, nullDefaultBits); >+ } >+ } > } > } > return originalMethod.tagBits; >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java >index 642388d..bfb4f2b 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.lookup; > >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java >index 9522a2c..9c030ec 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,6 +7,9 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contributions for >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 365519 - editorial cleanup after bug 186342 and bug 365387 > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.lookup; > >@@ -143,7 +146,7 @@ > } > void checkConcreteInheritedMethod(MethodBinding concreteMethod, MethodBinding[] abstractMethods) { > super.checkConcreteInheritedMethod(concreteMethod, abstractMethods); >- >+ boolean analyseNullAnnotations = this.environment.globalOptions.isAnnotationBasedNullAnalysisEnabled; > for (int i = 0, l = abstractMethods.length; i < l; i++) { > MethodBinding abstractMethod = abstractMethods[i]; > if (concreteMethod.isVarargs() != abstractMethod.isVarargs()) >@@ -164,6 +167,8 @@ > || this.type.superclass.erasure().findSuperTypeOriginatingFrom(originalInherited.declaringClass) == null) > this.type.addSyntheticBridgeMethod(originalInherited, concreteMethod.original()); > } >+ if (analyseNullAnnotations && !concreteMethod.isStatic() && !abstractMethod.isStatic()) >+ checkNullSpecInheritance(concreteMethod, abstractMethod); > } > } > void checkForBridgeMethod(MethodBinding currentMethod, MethodBinding inheritedMethod, MethodBinding[] allInheritedMethods) { >@@ -320,7 +325,9 @@ > // class Y { <T> void foo(T t) {} } > // abstract class X extends Y implements I {} > >- if (inheritedMethod.declaringClass.isInterface() || inheritedMethod.isStatic()) return; >+ if (inheritedMethod.isStatic()) return; >+ if (this.environment.globalOptions.complianceLevel < ClassFileConstants.JDK1_7 && inheritedMethod.declaringClass.isInterface()) >+ return; // JDK7 checks for name clashes in interface inheritance, while JDK6 and below don't. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=354229 > > detectInheritedNameClash(inheritedMethod.original(), otherInheritedMethod.original()); > } >@@ -358,6 +365,104 @@ > } > > return false; >+} >+void checkAgainstInheritedMethods(MethodBinding currentMethod, MethodBinding[] methods, int length, MethodBinding[] allInheritedMethods) >+{ >+ super.checkAgainstInheritedMethods(currentMethod, methods, length, allInheritedMethods); >+ if (this.environment.globalOptions.isAnnotationBasedNullAnalysisEnabled) { >+ for (int i = length; --i >= 0;) >+ if (!currentMethod.isStatic() && !methods[i].isStatic()) >+ checkNullSpecInheritance(currentMethod, methods[i]); >+ } >+} >+ >+void checkNullSpecInheritance(MethodBinding currentMethod, MethodBinding inheritedMethod) { >+ // precondition: caller has checked whether annotation-based null analysis is enabled. >+ long inheritedBits = inheritedMethod.tagBits; >+ long currentBits = currentMethod.tagBits; >+ AbstractMethodDeclaration srcMethod = null; >+ if (this.type.equals(currentMethod.declaringClass)) // is currentMethod from the current type? >+ srcMethod = currentMethod.sourceMethod(); >+ >+ // return type: >+ if ((inheritedBits & TagBits.AnnotationNonNull) != 0) { >+ long currentNullBits = currentBits & (TagBits.AnnotationNonNull|TagBits.AnnotationNullable); >+ if (currentNullBits != TagBits.AnnotationNonNull) { >+ if (srcMethod != null) { >+ this.type.scope.problemReporter().illegalReturnRedefinition(srcMethod, inheritedMethod, >+ this.environment.getNonNullAnnotationName()); >+ } else { >+ this.type.scope.problemReporter().cannotImplementIncompatibleNullness(currentMethod, inheritedMethod); >+ return; >+ } >+ } >+ } >+ >+ // parameters: >+ Argument[] currentArguments = srcMethod == null ? null : srcMethod.arguments; >+ if (inheritedMethod.parameterNonNullness != null) { >+ // inherited method has null-annotations, check compatibility: >+ >+ int length = inheritedMethod.parameterNonNullness.length; >+ for (int i = 0; i < length; i++) { >+ Argument currentArgument = currentArguments == null ? null : currentArguments[i]; >+ >+ Boolean inheritedNonNullNess = inheritedMethod.parameterNonNullness[i]; >+ Boolean currentNonNullNess = (currentMethod.parameterNonNullness == null) >+ ? null : currentMethod.parameterNonNullness[i]; >+ if (inheritedNonNullNess != null) { // super has a null annotation >+ if (currentNonNullNess == null) { // current parameter lacks null annotation >+ boolean needNonNull = false; >+ char[][] annotationName; >+ if (inheritedNonNullNess == Boolean.TRUE) { >+ needNonNull = true; >+ annotationName = this.environment.getNonNullAnnotationName(); >+ } else { >+ annotationName = this.environment.getNullableAnnotationName(); >+ } >+ if (currentArgument != null) { >+ this.type.scope.problemReporter().parameterLackingNullAnnotation( >+ currentArgument, >+ inheritedMethod.declaringClass, >+ needNonNull, >+ annotationName); >+ continue; >+ } else { >+ this.type.scope.problemReporter().cannotImplementIncompatibleNullness(currentMethod, inheritedMethod); >+ break; >+ } >+ } >+ } >+ if (inheritedNonNullNess != Boolean.TRUE) { // super parameter is not restricted to @NonNull >+ if (currentNonNullNess == Boolean.TRUE) { // current parameter is restricted to @NonNull >+ if (currentArgument != null) >+ this.type.scope.problemReporter().illegalRedefinitionToNonNullParameter( >+ currentArgument, >+ inheritedMethod.declaringClass, >+ inheritedNonNullNess == null >+ ? null >+ : this.environment.getNullableAnnotationName()); >+ else >+ this.type.scope.problemReporter().cannotImplementIncompatibleNullness(currentMethod, inheritedMethod); >+ } >+ } >+ } >+ } else if (currentMethod.parameterNonNullness != null) { >+ // super method has no annotations but current has >+ for (int i = 0; i < currentMethod.parameterNonNullness.length; i++) { >+ if (currentMethod.parameterNonNullness[i] == Boolean.TRUE) { // tightening from unconstrained to @NonNull >+ if (currentArguments != null) { >+ this.type.scope.problemReporter().illegalRedefinitionToNonNullParameter( >+ currentArguments[i], >+ inheritedMethod.declaringClass, >+ null); >+ } else { >+ this.type.scope.problemReporter().cannotImplementIncompatibleNullness(currentMethod, inheritedMethod); >+ break; >+ } >+ } >+ } >+ } > } > > void reportRawReferences() { >@@ -932,7 +1037,7 @@ > boolean isUnsafeReturnTypeOverride(MethodBinding currentMethod, MethodBinding inheritedMethod) { > // called when currentMethod's return type is NOT compatible with inheritedMethod's return type > >- // JLS 3 §8.4.5: more are accepted, with an unchecked conversion >+ // JLS 3 �8.4.5: more are accepted, with an unchecked conversion > if (currentMethod.returnType == inheritedMethod.returnType.erasure()) { > TypeBinding[] currentParams = currentMethod.parameters; > TypeBinding[] inheritedParams = inheritedMethod.parameters; >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MostSpecificExceptionMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MostSpecificExceptionMethodBinding.java >index 5efc685..37d0536 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MostSpecificExceptionMethodBinding.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MostSpecificExceptionMethodBinding.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2008 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contribution for bug 186342 - [compiler][null] Using annotations for null checking > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.lookup; > >@@ -27,6 +28,7 @@ > mostSpecificExceptions, > originalMethod.declaringClass); > this.originalMethod = originalMethod; >+ this.parameterNonNullness = originalMethod.parameterNonNullness; > } > > public MethodBinding original() { >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java >index 4fc8606..af25174 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,8 +7,12 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contribution for bug 365662 - [compiler][null] warn on contradictory and redundant null annotations > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.lookup; >+ >+import org.eclipse.jdt.internal.compiler.ast.ASTNode; >+import org.eclipse.jdt.internal.compiler.ast.Annotation; > > public class NestedTypeBinding extends SourceTypeBinding { > >@@ -107,6 +111,17 @@ > return synthLocal; > } > >+protected void checkRedundantNullnessDefaultRecurse(ASTNode location, Annotation[] annotations, long annotationTagBits) { >+ ReferenceBinding currentType = this.enclosingType; >+ do { >+ if (!((SourceTypeBinding)currentType).checkRedundantNullnessDefaultOne(location, annotations, annotationTagBits)) { >+ return; >+ } >+ currentType = currentType.enclosingType(); >+ } while (currentType instanceof SourceTypeBinding); >+ super.checkRedundantNullnessDefaultRecurse(location, annotations, annotationTagBits); >+} >+ > /* Answer the receiver's enclosing type... null if the receiver is a top level type. > */ > public ReferenceBinding enclosingType() { >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java >index 0e59232..f139509 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,6 +7,10 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contributions for >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 365519 - editorial cleanup after bug 186342 and bug 365387 >+ * bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.lookup; > >@@ -22,6 +26,11 @@ > public LookupEnvironment environment; > HashtableOfType knownTypes; > HashtableOfPackage knownPackages; >+ >+ // code representing the default that has been defined for this package (using @NonNullByDefault) >+ // one of Binding.{NO_NULL_DEFAULT,NULL_UNSPECIFIED_BY_DEFAULT,NONNULL_BY_DEFAULT} >+ protected int defaultNullness = NO_NULL_DEFAULT; >+ > protected PackageBinding() { > // for creating problem package > } >@@ -36,6 +45,8 @@ > this.environment = environment; > this.knownTypes = null; // initialized if used... class counts can be very large 300-600 > this.knownPackages = new HashtableOfPackage(3); // sub-package counts are typically 0-3 >+ if (compoundName != CharOperation.NO_CHAR_CHAR) >+ checkIfNullAnnotationPackage(); > } > > public PackageBinding(LookupEnvironment environment) { >@@ -58,6 +69,9 @@ > if (this.knownTypes == null) > this.knownTypes = new HashtableOfType(25); > this.knownTypes.put(element.compoundName[element.compoundName.length - 1], element); >+ if (this.environment.globalOptions.isAnnotationBasedNullAnalysisEnabled) >+ if (element.isAnnotationType() || element instanceof UnresolvedReferenceBinding) // unresolved types don't yet have the modifiers set >+ checkIfNullAnnotationType(element); > } > > void clearMissingTagBit() { >@@ -230,6 +244,50 @@ > return ProblemReasons.NoError; > } > >+ >+void checkIfNullAnnotationPackage() { >+ LookupEnvironment env = this.environment; >+ if (env.globalOptions.isAnnotationBasedNullAnalysisEnabled) { >+ if (isPackageOfQualifiedTypeName(this.compoundName, env.getNullableAnnotationName())) >+ env.nullableAnnotationPackage = this; >+ if (isPackageOfQualifiedTypeName(this.compoundName, env.getNonNullAnnotationName())) >+ env.nonnullAnnotationPackage = this; >+ if (isPackageOfQualifiedTypeName(this.compoundName, env.getNonNullByDefaultAnnotationName())) >+ env.nonnullByDefaultAnnotationPackage = this; >+ } >+} >+ >+private boolean isPackageOfQualifiedTypeName(char[][] packageName, char[][] typeName) { >+ int length; >+ if (typeName == null || (length = packageName.length) != typeName.length -1) >+ return false; >+ for (int i=0; i<length; i++) >+ if (!CharOperation.equals(packageName[i], typeName[i])) >+ return false; >+ return true; >+} >+ >+void checkIfNullAnnotationType(ReferenceBinding type) { >+ // check if type is one of the configured null annotation types >+ // if so mark as a well known type using the corresponding typeID: >+ if (this.environment.nullableAnnotationPackage == this >+ && CharOperation.equals(type.compoundName, this.environment.getNullableAnnotationName())) { >+ type.id = TypeIds.T_ConfiguredAnnotationNullable; >+ if (!(type instanceof UnresolvedReferenceBinding)) // unresolved will need to check back for the resolved type >+ this.environment.nullableAnnotationPackage = null; // don't check again >+ } else if (this.environment.nonnullAnnotationPackage == this >+ && CharOperation.equals(type.compoundName, this.environment.getNonNullAnnotationName())) { >+ type.id = TypeIds.T_ConfiguredAnnotationNonNull; >+ if (!(type instanceof UnresolvedReferenceBinding)) // unresolved will need to check back for the resolved type >+ this.environment.nonnullAnnotationPackage = null; // don't check again >+ } else if (this.environment.nonnullByDefaultAnnotationPackage == this >+ && CharOperation.equals(type.compoundName, this.environment.getNonNullByDefaultAnnotationName())) { >+ type.id = TypeIds.T_ConfiguredAnnotationNonNullByDefault; >+ if (!(type instanceof UnresolvedReferenceBinding)) // unresolved will need to check back for the resolved type >+ this.environment.nonnullByDefaultAnnotationPackage = null; // don't check again >+ } >+} >+ > public char[] readableName() /*java.lang*/ { > return CharOperation.concatWith(this.compoundName, '.'); > } >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java >index 1eb176f..31710c4 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contribution for bug 186342 - [compiler][null] Using annotations for null checking > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.lookup; > >@@ -301,6 +302,7 @@ > ? originalMethod.returnType // no substitution if original was static > : Scope.substitute(rawType, originalMethod.returnType)); > this.wasInferred = false; // not resulting from method invocation inferrence >+ this.parameterNonNullness = originalMethod.parameterNonNullness; > } > > /** >@@ -342,6 +344,7 @@ > } > } > this.wasInferred = true;// resulting from method invocation inferrence >+ this.parameterNonNullness = originalMethod.parameterNonNullness; > } > > /* >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedMethodBinding.java >index 22b5afa..c7f8ad3 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedMethodBinding.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedMethodBinding.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contribution for bug 186342 - [compiler][null] Using annotations for null checking > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.lookup; > >@@ -38,6 +39,7 @@ > * is substituted by a raw type. > */ > this.tagBits = originalMethod.tagBits & ~TagBits.HasMissingType; >+ this.parameterNonNullness = originalMethod.parameterNonNullness; > > final TypeVariableBinding[] originalVariables = originalMethod.typeVariables; > Substitution substitution = null; >@@ -150,6 +152,7 @@ > * is substituted by a raw type. > */ > this.tagBits = originalMethod.tagBits & ~TagBits.HasMissingType; >+ this.parameterNonNullness = originalMethod.parameterNonNullness; > > final TypeVariableBinding[] originalVariables = originalMethod.typeVariables; > Substitution substitution = null; >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java >index 5458a30..1ecf7aa 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2005, 2011 IBM Corporation and others. >+ * Copyright (c) 2005, 2012 IBM Corporation 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 >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.lookup; > >@@ -629,6 +630,13 @@ > return this.type.hasMemberTypes(); > } > >+ public boolean hasTypeBit(int bit) { >+ TypeBinding erasure = erasure(); >+ if (erasure instanceof ReferenceBinding) >+ return ((ReferenceBinding) erasure).hasTypeBit(bit); >+ return false; >+ } >+ > /** > * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#implementsMethod(MethodBinding) > */ >@@ -667,7 +675,7 @@ > } > break; > case Binding.INTERSECTION_TYPE : >- this.tagBits |= TagBits.HasDirectWildcard; >+ this.tagBits |= TagBits.HasDirectWildcard | TagBits.IsBoundParameterizedType; // Surely NOT X<?,?>, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=366131 > break; > default : > this.tagBits |= TagBits.IsBoundParameterizedType; >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReasons.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReasons.java >index e156bdf..4373687 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReasons.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReasons.java >@@ -27,4 +27,5 @@ > final int TypeArgumentsForRawGenericMethod = 13; // for generic method > final int InvalidTypeForStaticImport = 14; > final int InvalidTypeForAutoManagedResource = 15; >+ final int VarargsElementTypeNotVisible = 16; > } >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReferenceBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReferenceBinding.java >index efc1bc2..5d9c344 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReferenceBinding.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReferenceBinding.java >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.lookup; > >@@ -40,6 +41,12 @@ > return this.closestMatch; > } > >+public boolean hasTypeBit(int bit) { >+ if (this.closestMatch != null) >+ return this.closestMatch.hasTypeBit(bit); >+ return false; >+} >+ > /* API > * Answer the problem id associated with the receiver. > * NoError if the receiver is a valid binding. >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java >index c26cc15..ca96657 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java >@@ -1,12 +1,18 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contributions for >+ * bug 349326 - [1.7] new warning for missing try-with-resources >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 365519 - editorial cleanup after bug 186342 and bug 365387 >+ * bug 358903 - Filter practically unimportant resource leak warnings >+ * bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.lookup; > >@@ -41,7 +47,11 @@ > > private SimpleLookupTable compatibleCache; > >- public static final ReferenceBinding LUB_GENERIC = new ReferenceBinding() { /* used for lub computation */}; >+ int typeBits; // additional bits characterizing this type >+ >+ public static final ReferenceBinding LUB_GENERIC = new ReferenceBinding() { /* used for lub computation */ >+ public boolean hasTypeBit(int bit) { return false; } >+ }; > > private static final Comparator FIELD_COMPARATOR = new Comparator() { > public int compare(Object o1, Object o2) { >@@ -361,12 +371,13 @@ > } > > public void computeId() { >+ // note that more (configurable) ids are assigned from PackageBinding#checkIfNullAnnotationType() >+ > // try to avoid multiple checks against a package/type name > switch (this.compoundName.length) { > > case 3 : >- if (!CharOperation.equals(TypeConstants.JAVA, this.compoundName[0]) >- && !CharOperation.equals(TypeConstants.JAVAX, this.compoundName[0])) >+ if (!CharOperation.equals(TypeConstants.JAVA, this.compoundName[0])) > return; > > char[] packageName = this.compoundName[1]; >@@ -374,24 +385,15 @@ > char[] typeName = this.compoundName[2]; > if (typeName.length == 0) return; // just to be safe > // remaining types MUST be in java.*.* >- if (CharOperation.equals(TypeConstants.JAVAX, this.compoundName[0])) { >- if (CharOperation.equals(TypeConstants.ANNOTATION, this.compoundName[1])) { >- switch (typeName[0]) { >- case 'P' : >- if (CharOperation.equals(typeName, TypeConstants.JAVAX_ANNOTATION_POSTCONSTRUCT[2])) >- this.id = TypeIds.T_JavaxAnnotationPostConstruct; >- if (CharOperation.equals(typeName, TypeConstants.JAVAX_ANNOTATION_PREDESTROY[2])) >- this.id = TypeIds.T_JavaxAnnotationPreDestroy; >- return; >- } >- } >- return; >- } > if (!CharOperation.equals(TypeConstants.LANG, this.compoundName[1])) { > switch (packageName[0]) { > case 'i' : > if (CharOperation.equals(packageName, TypeConstants.IO)) { > switch (typeName[0]) { >+ case 'C' : >+ if (CharOperation.equals(typeName, TypeConstants.JAVA_IO_CLOSEABLE[2])) >+ this.typeBits |= TypeIds.BitCloseable; // don't assign id, only typeBit (for analysis of resource leaks) >+ return; > case 'E' : > if (CharOperation.equals(typeName, TypeConstants.JAVA_IO_EXTERNALIZABLE[2])) > this.id = TypeIds.T_JavaIoExternalizable; >@@ -438,8 +440,10 @@ > case 'A' : > switch(typeName.length) { > case 13 : >- if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_AUTOCLOSEABLE[2])) >+ if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_AUTOCLOSEABLE[2])) { > this.id = TypeIds.T_JavaLangAutoCloseable; >+ this.typeBits |= TypeIds.BitAutoCloseable; >+ } > return; > case 14: > if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ASSERTIONERROR[2])) >@@ -937,6 +941,8 @@ > public final boolean hasRestrictedAccess() { > return (this.modifiers & ExtraCompilerModifiers.AccRestrictedAccess) != 0; > } >+/** Answer an additional bit characterizing this type, like {@link TypeIds#BitAutoCloseable}. */ >+abstract public boolean hasTypeBit(int bit); > > /** Answer true if the receiver implements anInterface or is identical to anInterface. > * If searchHierarchy is true, then also search the receiver's superclasses. >@@ -1446,4 +1452,50 @@ > public FieldBinding[] unResolvedFields() { > return Binding.NO_FIELDS; > } >+ >+/* >+ * If a type - known to be a Closeable - is mentioned in one of our white lists >+ * answer the typeBit for the white list (BitWrapperCloseable or BitResourceFreeCloseable). >+ */ >+protected int applyCloseableWhitelists() { >+ switch (this.compoundName.length) { >+ case 3: >+ if (CharOperation.equals(TypeConstants.JAVA, this.compoundName[0])) { >+ if (CharOperation.equals(TypeConstants.IO, this.compoundName[1])) { >+ char[] simpleName = this.compoundName[2]; >+ int l = TypeConstants.JAVA_IO_WRAPPER_CLOSEABLES.length; >+ for (int i = 0; i < l; i++) { >+ if (CharOperation.equals(simpleName, TypeConstants.JAVA_IO_WRAPPER_CLOSEABLES[i])) >+ return TypeIds.BitWrapperCloseable; >+ } >+ l = TypeConstants.JAVA_IO_RESOURCE_FREE_CLOSEABLES.length; >+ for (int i = 0; i < l; i++) { >+ if (CharOperation.equals(simpleName, TypeConstants.JAVA_IO_RESOURCE_FREE_CLOSEABLES[i])) >+ return TypeIds.BitResourceFreeCloseable; >+ } >+ } >+ } >+ break; >+ case 4: >+ if (CharOperation.equals(TypeConstants.JAVA, this.compoundName[0])) { >+ if (CharOperation.equals(TypeConstants.UTIL, this.compoundName[1])) { >+ if (CharOperation.equals(TypeConstants.ZIP, this.compoundName[2])) { >+ char[] simpleName = this.compoundName[3]; >+ int l = TypeConstants.JAVA_UTIL_ZIP_WRAPPER_CLOSEABLES.length; >+ for (int i = 0; i < l; i++) { >+ if (CharOperation.equals(simpleName, TypeConstants.JAVA_UTIL_ZIP_WRAPPER_CLOSEABLES[i])) >+ return TypeIds.BitWrapperCloseable; >+ } >+ } >+ } >+ } >+ break; >+ } >+ int l = TypeConstants.OTHER_WRAPPER_CLOSEABLES.length; >+ for (int i = 0; i < l; i++) { >+ if (CharOperation.equals(this.compoundName, TypeConstants.OTHER_WRAPPER_CLOSEABLES[i])) >+ return TypeIds.BitWrapperCloseable; >+ } >+ return 0; >+} > } >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java >index 146c98f..25fee09 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contribution for bug 186342 [compiler][null] Using annotations for null checking > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.lookup; > >@@ -527,6 +528,15 @@ > * in case the method was originally compatible, then simply answer it back. > */ > protected final MethodBinding computeCompatibleMethod(MethodBinding method, TypeBinding[] arguments, InvocationSite invocationSite) { >+ return computeCompatibleMethod(method, arguments, invocationSite, false); >+ } >+ /** >+ * Internal use only >+ * Given a method, returns null if arguments cannot be converted to parameters. >+ * Will answer a substituted method in case the method was generic and type inference got triggered; >+ * in case the method was originally compatible, then simply answer it back. >+ */ >+ protected final MethodBinding computeCompatibleMethod(MethodBinding method, TypeBinding[] arguments, InvocationSite invocationSite, boolean tiebreakingVarargsMethods) { > TypeBinding[] genericTypeArguments = invocationSite.genericTypeArguments(); > TypeBinding[] parameters = method.parameters; > TypeVariableBinding[] typeVariables = method.typeVariables; >@@ -571,14 +581,26 @@ > } > } > >- if (parameterCompatibilityLevel(method, arguments) > NOT_COMPATIBLE) { >+ int compatibilityLevel; >+ if ((compatibilityLevel = parameterCompatibilityLevel(method, arguments, tiebreakingVarargsMethods)) > NOT_COMPATIBLE) { >+ if (compatibilityLevel == VARARGS_COMPATIBLE) { >+ TypeBinding varargsElementType = method.parameters[method.parameters.length - 1].leafComponentType(); >+ if (varargsElementType instanceof ReferenceBinding) { >+ if (!((ReferenceBinding) varargsElementType).canBeSeenBy(this)) { >+ return new ProblemMethodBinding(method, method.selector, genericTypeArguments, ProblemReasons.VarargsElementTypeNotVisible); >+ } >+ } >+ } > if ((method.tagBits & TagBits.AnnotationPolymorphicSignature) != 0) { > // generate polymorphic method > return this.environment().createPolymorphicMethod(method, arguments); > } > return method; > } >- if (genericTypeArguments != null) >+ // if method is generic and type arguments have been supplied, only then answer a problem >+ // of ParameterizedMethodTypeMismatch, else a non-generic method was invoked using type arguments >+ // in which case this problem category will be bogus >+ if (genericTypeArguments != null && typeVariables != Binding.NO_TYPE_VARIABLES) > return new ProblemMethodBinding(method, method.selector, arguments, ProblemReasons.ParameterizedMethodTypeMismatch); > return null; // incompatible > } >@@ -2389,6 +2411,40 @@ > return new ProblemReferenceBinding(compoundName, null /* no closest match since search for pkg*/, ProblemReasons.NotFound); > } > >+ /* Answer the package from the compoundName or null if it begins with a type. >+ * Intended to be used while resolving a package name only. >+ * >+ * Internal use only >+ */ >+ public final Binding getOnlyPackage(char[][] compoundName) { >+ compilationUnitScope().recordQualifiedReference(compoundName); >+ Binding binding = getTypeOrPackage(compoundName[0], Binding.PACKAGE, true); >+ if (binding == null || !binding.isValidBinding()) { >+ char[][] qName = new char[][] { compoundName[0] }; >+ return new ProblemReferenceBinding(qName, null /* no closest match since search for pkg*/, ProblemReasons.NotFound); >+ } >+ if (!(binding instanceof PackageBinding)) { >+ return null; // compoundName does not start with a package >+ } >+ >+ int currentIndex = 1, length = compoundName.length; >+ PackageBinding packageBinding = (PackageBinding) binding; >+ while (currentIndex < length) { >+ binding = packageBinding.getPackage(compoundName[currentIndex++]); >+ if (binding == null) { >+ return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, currentIndex), null /* no closest match since search for pkg*/, ProblemReasons.NotFound); >+ } >+ if (!binding.isValidBinding()) { >+ return new ProblemReferenceBinding( >+ CharOperation.subarray(compoundName, 0, currentIndex), >+ binding instanceof ReferenceBinding ? (ReferenceBinding)((ReferenceBinding)binding).closestMatch() : null, >+ binding.problemId()); >+ } >+ packageBinding = (PackageBinding) binding; >+ } >+ return packageBinding; >+ } >+ > /* Answer the type binding that corresponds the given name, starting the lookup in the receiver. > * The name provided is a simple source name (e.g., "Object" , "Point", ...) > */ >@@ -2678,7 +2734,53 @@ > } > } > } >- >+ // walk single static imports. A type found here will shadow types with same name in other CU's, or types coming >+ // from on-demand imports. JLS 7.5.3 >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=318401 >+ if (imports != null) { >+ ReferenceBinding type = null; >+ nextImport : for (int i = 0, length = imports.length; i < length; i++) { >+ ImportBinding importBinding = imports[i]; >+ if (importBinding.isStatic()) { >+ ReferenceBinding temp = null; >+ if (CharOperation.equals(importBinding.compoundName[importBinding.compoundName.length - 1], name)) { >+ Binding resolvedImport = importBinding.resolvedImport; >+ if (resolvedImport == null) continue nextImport; >+ if (resolvedImport instanceof MethodBinding || resolvedImport instanceof FieldBinding) { >+ // check to see if there are also member types with the same name >+ // must find the importRef's type again since the method/field can be from an inherited type >+ // see StaticImportTest#test084 for more clarity >+ char[][] importName = importBinding.reference.tokens; >+ TypeBinding referencedType = getType(importName, importName.length - 1); >+ if (referencedType != null && referencedType instanceof ReferenceBinding) { >+ temp = findMemberType(name, (ReferenceBinding) referencedType); >+ } >+ } >+ if (temp != null && temp.isStatic() && temp != type) { >+ if (temp.isValidBinding()) { >+ if (!temp.canBeSeenBy(unitScope.fPackage)) { >+ // Answer error binding - type is not visible >+ foundType = new ProblemReferenceBinding(new char[][]{name}, type, ProblemReasons.NotVisible); >+ } else { >+ ImportReference importReference = importBinding.reference; >+ if (importReference != null) { >+ importReference.bits |= ASTNode.Used; >+ } >+ type = temp; >+ } >+ } else if (foundType == null) { >+ foundType = temp; >+ } >+ } >+ } >+ } >+ } >+ if (type != null) { >+ if (typeOrPackageCache != null) >+ typeOrPackageCache.put(name, type); >+ return type; >+ } >+ } > // check if the name is in the current package, skip it if its a sub-package > PackageBinding currentPackage = unitScope.fPackage; > unitScope.recordReference(currentPackage.compoundName, name); >@@ -2878,6 +2980,7 @@ > return null; > } > >+ // Tie break IS running to determine the most specific method binding. > protected boolean isAcceptableMethod(MethodBinding one, MethodBinding two) { > TypeBinding[] oneParams = one.parameters; > TypeBinding[] twoParams = two.parameters; >@@ -2924,8 +3027,9 @@ > } > } else { > if (i == oneParamsLength - 1 && one.isVarargs() && two.isVarargs()) { >+ TypeBinding oType = ((ArrayBinding) oneParam).elementsType(); > TypeBinding eType = ((ArrayBinding) twoParam).elementsType(); >- if (oneParam == eType || oneParam.isCompatibleWith(eType)) >+ if (oType == eType || oType.isCompatibleWith(eType)) > return true; // special case to choose between 2 varargs methods when the last arg is Object[] > } > return false; >@@ -2935,17 +3039,12 @@ > } > > if (one.isVarargs() && two.isVarargs()) { >- if (oneParamsLength > twoParamsLength) { >- // special case when autoboxing makes (int, int...) better than (Object...) but not (int...) or (Integer, int...) >- if (((ArrayBinding) twoParams[twoParamsLength - 1]).elementsType().id != TypeIds.T_JavaLangObject) >- return false; >- } > // check that each parameter before the vararg parameters are compatible (no autoboxing allowed here) > for (int i = (oneParamsLength > twoParamsLength ? twoParamsLength : oneParamsLength) - 2; i >= 0; i--) > if (oneParams[i] != twoParams[i] && !oneParams[i].isCompatibleWith(twoParams[i])) > return false; >- if (parameterCompatibilityLevel(one, twoParams) == NOT_COMPATIBLE >- && parameterCompatibilityLevel(two, oneParams) == VARARGS_COMPATIBLE) >+ if (parameterCompatibilityLevel(one, twoParams, true) == NOT_COMPATIBLE >+ && parameterCompatibilityLevel(two, oneParams, true) == VARARGS_COMPATIBLE) > return true; > } > return false; >@@ -2980,6 +3079,7 @@ > /* Answer true if the scope is nested inside a given method declaration > */ > public final boolean isDefinedInMethod(MethodBinding method) { >+ method = method.original(); // https://bugs.eclipse.org/bugs/show_bug.cgi?id=350738 > Scope scope = this; > do { > if (scope instanceof MethodScope) { >@@ -3009,7 +3109,7 @@ > // test that the enclosingType is not part of the compilation unit > SourceTypeBinding[] topLevelTypes = ((CompilationUnitScope) unitScope).topLevelTypes; > for (int i = topLevelTypes.length; --i >= 0;) >- if (topLevelTypes[i] == enclosingType) >+ if (topLevelTypes[i] == enclosingType.original()) > return true; > return false; > } >@@ -3744,7 +3844,7 @@ > methodToTest = pNext.originalMethod; > } > } >- MethodBinding acceptable = computeCompatibleMethod(methodToTest, tiebreakMethod.parameters, tieBreakInvocationSite); >+ MethodBinding acceptable = computeCompatibleMethod(methodToTest, tiebreakMethod.parameters, tieBreakInvocationSite, level == VARARGS_COMPATIBLE); > /* There are 4 choices to consider with current & next : > foo(B) & foo(A) where B extends A > 1. the 2 methods are equal (both accept each others parameters) -> want to continue >@@ -3916,6 +4016,9 @@ > } > > public int parameterCompatibilityLevel(MethodBinding method, TypeBinding[] arguments) { >+ return parameterCompatibilityLevel(method, arguments, false); >+ } >+ public int parameterCompatibilityLevel(MethodBinding method, TypeBinding[] arguments, boolean tiebreakingVarargsMethods) { > TypeBinding[] parameters = method.parameters; > int paramLength = parameters.length; > int argLength = arguments.length; >@@ -3942,11 +4045,14 @@ > TypeBinding param = parameters[lastIndex]; // is an ArrayBinding by definition > TypeBinding arg = arguments[lastIndex]; > if (param != arg) { >- level = parameterCompatibilityLevel(arg, param, env); >+ level = parameterCompatibilityLevel(arg, param, env, tiebreakingVarargsMethods); > if (level == NOT_COMPATIBLE) { > // expect X[], is it called with X > param = ((ArrayBinding) param).elementsType(); >- if (parameterCompatibilityLevel(arg, param, env) == NOT_COMPATIBLE) >+ if (tiebreakingVarargsMethods) { >+ arg = ((ArrayBinding) arg).elementsType(); >+ } >+ if (parameterCompatibilityLevel(arg, param, env, tiebreakingVarargsMethods) == NOT_COMPATIBLE) > return NOT_COMPATIBLE; > level = VARARGS_COMPATIBLE; // varargs support needed > } >@@ -3955,8 +4061,8 @@ > if (paramLength < argLength) { // all remaining argument types must be compatible with the elementsType of varArgType > TypeBinding param = ((ArrayBinding) parameters[lastIndex]).elementsType(); > for (int i = lastIndex; i < argLength; i++) { >- TypeBinding arg = arguments[i]; >- if (param != arg && parameterCompatibilityLevel(arg, param, env) == NOT_COMPATIBLE) >+ TypeBinding arg = (tiebreakingVarargsMethods && (i == (argLength - 1))) ? ((ArrayBinding)arguments[i]).elementsType() : arguments[i]; >+ if (param != arg && parameterCompatibilityLevel(arg, param, env, tiebreakingVarargsMethods) == NOT_COMPATIBLE) > return NOT_COMPATIBLE; > } > } else if (lastIndex != argLength) { // can call foo(int i, X ... x) with foo(1) but NOT foo(); >@@ -3970,9 +4076,9 @@ > // now compare standard arguments from 0 to lastIndex > for (int i = 0; i < lastIndex; i++) { > TypeBinding param = parameters[i]; >- TypeBinding arg = arguments[i]; >+ TypeBinding arg = (tiebreakingVarargsMethods && (i == (argLength - 1))) ? ((ArrayBinding)arguments[i]).elementsType() : arguments[i]; > if (arg != param) { >- int newLevel = parameterCompatibilityLevel(arg, param, env); >+ int newLevel = parameterCompatibilityLevel(arg, param, env, tiebreakingVarargsMethods); > if (newLevel == NOT_COMPATIBLE) > return NOT_COMPATIBLE; > if (newLevel > level) >@@ -3982,10 +4088,19 @@ > return level; > } > >- private int parameterCompatibilityLevel(TypeBinding arg, TypeBinding param, LookupEnvironment env) { >+ private int parameterCompatibilityLevel(TypeBinding arg, TypeBinding param, LookupEnvironment env, boolean tieBreakingVarargsMethods) { > // only called if env.options.sourceLevel >= ClassFileConstants.JDK1_5 > if (arg.isCompatibleWith(param)) > return COMPATIBLE; >+ if (tieBreakingVarargsMethods) { >+ /* 15.12.2.5 Choosing the Most Specific Method, ... One variable arity member method named m is more specific than >+ another variable arity member method of the same name if either ... Only subtypes relationship should be used. >+ Actually this is true even for fixed arity methods, but in practice is not an issue since we run the algorithm >+ multiple times for each compatibility level. >+ https://bugs.eclipse.org/bugs/show_bug.cgi?id=346038, https://bugs.eclipse.org/bugs/show_bug.cgi?id=346039. >+ */ >+ return NOT_COMPATIBLE; >+ } > if (arg.isBaseType() != param.isBaseType()) { > TypeBinding convertedType = env.computeBoxingType(arg); > if (convertedType == param || convertedType.isCompatibleWith(param)) >@@ -4176,4 +4291,18 @@ > } > return visibleIndex == 1 ? visible[0] : mostSpecificMethodBinding(visible, visibleIndex, argumentTypes, allocationSite, allocationType); > } >+ >+ public void validateNullAnnotation(long tagBits, TypeReference typeRef, Annotation[] annotations) { >+ long nullAnnotationTagBit = tagBits & (TagBits.AnnotationNonNull|TagBits.AnnotationNullable); >+ if (nullAnnotationTagBit != 0) { >+ TypeBinding type = typeRef.resolvedType; >+ if (type != null && type.isBaseType()) { >+ char[][] annotationName = (nullAnnotationTagBit == TagBits.AnnotationNonNull) >+ ? environment().getNonNullAnnotationName() >+ : environment().getNullableAnnotationName(); >+ problemReporter().illegalAnnotationForBaseType(typeRef, annotations, >+ annotationName[annotationName.length-1], nullAnnotationTagBit); >+ } >+ } >+ } > } >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java >index aabc37f..53a2b1b 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,7 +7,15 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >- * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 328281 - visibility leaks not detected when analyzing unused field in private class >+ * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for >+ * bug 328281 - visibility leaks not detected when analyzing unused field in private class >+ * bug 349326 - [1.7] new warning for missing try-with-resources >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 365836 - [compiler][null] Incomplete propagation of null defaults. >+ * bug 365519 - editorial cleanup after bug 186342 and bug 365387 >+ * bug 365662 - [compiler][null] warn on contradictory and redundant null annotations >+ * bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults >+ * bug 366063 - Compiler should not add synthetic @NonNull annotations > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.lookup; > >@@ -18,6 +26,7 @@ > import org.eclipse.jdt.internal.compiler.ast.ASTNode; > import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; > import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration; >+import org.eclipse.jdt.internal.compiler.ast.Annotation; > import org.eclipse.jdt.internal.compiler.ast.Argument; > import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; > import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; >@@ -52,6 +61,9 @@ > char[] genericReferenceTypeSignature; > > private SimpleLookupTable storedAnnotations = null; // keys are this ReferenceBinding & its fields and methods, value is an AnnotationHolder >+ >+ private int defaultNullness; >+ private int nullnessDefaultInitialized = 0; // 0: nothing; 1: type; 2: package > > public SourceTypeBinding(char[][] compoundName, PackageBinding fPackage, ClassScope scope) { > this.compoundName = compoundName; >@@ -779,6 +791,7 @@ > } > if ((this.tagBits & TagBits.AnnotationDeprecated) != 0) > this.modifiers |= ClassFileConstants.AccDeprecated; >+ evaluateNullAnnotations(this.tagBits); > } > return this.tagBits; > } >@@ -1063,6 +1076,11 @@ > return accessors[1]; > } > >+public boolean hasTypeBit(int bit) { >+ // source types initialize type bits during connectSuperclass/interfaces() >+ return (this.typeBits & bit) != 0; >+} >+ > /** > * @see org.eclipse.jdt.internal.compiler.lookup.Binding#initializeDeprecatedAnnotationTagBits() > */ >@@ -1081,6 +1099,8 @@ > this.modifiers |= ClassFileConstants.AccDeprecated; > } > } >+ if (CharOperation.equals(this.sourceName, TypeConstants.PACKAGE_INFO_NAME)) >+ getAnnotationTagBits(); // initialize > } > > // ensure the receiver knows its hierarchy & fields/methods so static imports can be resolved correctly >@@ -1233,8 +1253,16 @@ > int index = pLength; > // is erasure of signature of m2 same as signature of m1? > for (; --index >= 0;) { >- if (params1[index] != params2[index].erasure()) >- break; >+ if (params1[index] != params2[index].erasure()) { >+ // If one of them is a raw type >+ if (params1[index] instanceof RawTypeBinding) { >+ if (params2[index].erasure() != ((RawTypeBinding)params1[index]).actualType()) { >+ break; >+ } >+ } else { >+ break; >+ } >+ } > if (params1[index] == params2[index]) { > TypeBinding type = params1[index].leafComponentType(); > if (type instanceof SourceTypeBinding && type.typeVariables() != Binding.NO_TYPE_VARIABLES) { >@@ -1246,8 +1274,16 @@ > if (index >= 0 && index < pLength) { > // is erasure of signature of m1 same as signature of m2? > for (index = pLength; --index >= 0;) >- if (params1[index].erasure() != params2[index]) >- break; >+ if (params1[index].erasure() != params2[index]) { >+ // If one of them is a raw type >+ if (params2[index] instanceof RawTypeBinding) { >+ if (params1[index].erasure() != ((RawTypeBinding)params2[index]).actualType()) { >+ break; >+ } >+ } else { >+ break; >+ } >+ } > > } > if (index >= 0) { >@@ -1494,7 +1530,7 @@ > if (leafType instanceof ReferenceBinding && (((ReferenceBinding) leafType).modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0) > method.modifiers |= ExtraCompilerModifiers.AccGenericSignature; > newParameters[i] = parameterType; >- arg.binding = new LocalVariableBinding(arg, parameterType, arg.modifiers, true); >+ arg.binding = new LocalVariableBinding(arg, parameterType, arg.modifiers, true /*isArgument*/); > } > } > // only assign parameters if no problems are found >@@ -1567,12 +1603,123 @@ > typeParameters[i].binding = null; > return null; > } >+ if (this.scope.compilerOptions().isAnnotationBasedNullAnalysisEnabled) >+ createArgumentBindings(method); // need annotations resolved already at this point > if (foundReturnTypeProblem) > return method; // but its still unresolved with a null return type & is still connected to its method declaration > > method.modifiers &= ~ExtraCompilerModifiers.AccUnresolved; > return method; > } >+private void createArgumentBindings(MethodBinding method) { >+ // ensure nullness defaults are initialized at all enclosing levels: >+ switch (this.nullnessDefaultInitialized) { >+ case 0: >+ getAnnotationTagBits(); // initialize >+ //$FALL-THROUGH$ >+ case 1: >+ getPackage().isViewedAsDeprecated(); // initialize annotations >+ this.nullnessDefaultInitialized = 2; >+ } >+ AbstractMethodDeclaration methodDecl = method.sourceMethod(); >+ if (methodDecl != null) { >+ if (method.parameters != Binding.NO_PARAMETERS) >+ methodDecl.createArgumentBindings(); >+ if ((findNonNullDefault(methodDecl.scope, methodDecl.scope.environment()) == NONNULL_BY_DEFAULT)) { >+ method.fillInDefaultNonNullness(); >+ } >+ } >+} >+private void evaluateNullAnnotations(long annotationTagBits) { >+ if (this.nullnessDefaultInitialized > 0 || !this.scope.compilerOptions().isAnnotationBasedNullAnalysisEnabled) >+ return; >+ this.nullnessDefaultInitialized = 1; >+ // transfer nullness info from tagBits to this.nullnessDefaultAnnotation >+ int newDefaultNullness = NO_NULL_DEFAULT; >+ if ((annotationTagBits & TagBits.AnnotationNullUnspecifiedByDefault) != 0) >+ newDefaultNullness = NULL_UNSPECIFIED_BY_DEFAULT; >+ else if ((annotationTagBits & TagBits.AnnotationNonNullByDefault) != 0) >+ newDefaultNullness = NONNULL_BY_DEFAULT; >+ if (newDefaultNullness != NO_NULL_DEFAULT) { >+ if (CharOperation.equals(this.sourceName, TypeConstants.PACKAGE_INFO_NAME)) { >+ getPackage().defaultNullness = newDefaultNullness; >+ } else { >+ this.defaultNullness = newDefaultNullness; >+ TypeDeclaration typeDecl = this.scope.referenceContext; >+ long nullDefaultBits = annotationTagBits & (TagBits.AnnotationNullUnspecifiedByDefault|TagBits.AnnotationNonNullByDefault); >+ checkRedundantNullnessDefaultRecurse(typeDecl, typeDecl.annotations, nullDefaultBits); >+ } >+ } >+} >+ >+protected void checkRedundantNullnessDefaultRecurse(ASTNode location, Annotation[] annotations, long annotationTagBits) { >+ if (this.fPackage.defaultNullness != NO_NULL_DEFAULT) { >+ if ((this.fPackage.defaultNullness == NONNULL_BY_DEFAULT >+ && ((annotationTagBits & TagBits.AnnotationNonNullByDefault) != 0))) { >+ this.scope.problemReporter().nullDefaultAnnotationIsRedundant(location, annotations, this.fPackage); >+ } >+ return; >+ } >+} >+ >+// return: should caller continue searching? >+protected boolean checkRedundantNullnessDefaultOne(ASTNode location, Annotation[] annotations, long annotationTagBits) { >+ int thisDefault = this.defaultNullness; >+ if (thisDefault == NONNULL_BY_DEFAULT) { >+ if ((annotationTagBits & TagBits.AnnotationNonNullByDefault) != 0) { >+ this.scope.problemReporter().nullDefaultAnnotationIsRedundant(location, annotations, this); >+ } >+ return false; // different default means inner default is not redundant -> we're done >+ } >+ return true; >+} >+ >+/** >+ * Answer the nullness default applicable at the given method binding. >+ * Possible values: {@link Binding#NO_NULL_DEFAULT}, {@link Binding#NULL_UNSPECIFIED_BY_DEFAULT}, {@link Binding#NONNULL_BY_DEFAULT}. >+ * @param currentScope where to start search for lexically enclosing default >+ * @param environment gateway to options >+ */ >+private int findNonNullDefault(Scope currentScope, LookupEnvironment environment) { >+ // find the applicable default inside->out: >+ >+ SourceTypeBinding currentType = null; >+ while (currentScope != null) { >+ switch (currentScope.kind) { >+ case Scope.METHOD_SCOPE: >+ AbstractMethodDeclaration referenceMethod = ((MethodScope)currentScope).referenceMethod(); >+ if (referenceMethod != null && referenceMethod.binding != null) { >+ long methodTagBits = referenceMethod.binding.tagBits; >+ if ((methodTagBits & TagBits.AnnotationNonNullByDefault) != 0) >+ return NONNULL_BY_DEFAULT; >+ if ((methodTagBits & TagBits.AnnotationNullUnspecifiedByDefault) != 0) >+ return NULL_UNSPECIFIED_BY_DEFAULT; >+ } >+ break; >+ case Scope.CLASS_SCOPE: >+ currentType = ((ClassScope)currentScope).referenceContext.binding; >+ if (currentType != null) { >+ int foundDefaultNullness = currentType.defaultNullness; >+ if (foundDefaultNullness != NO_NULL_DEFAULT) { >+ return foundDefaultNullness; >+ } >+ } >+ break; >+ } >+ currentScope = currentScope.parent; >+ } >+ >+ // package >+ if (currentType != null) { >+ int foundDefaultNullness = currentType.getPackage().defaultNullness; >+ if (foundDefaultNullness != NO_NULL_DEFAULT) { >+ return foundDefaultNullness; >+ } >+ } >+ >+ return NO_NULL_DEFAULT; >+} >+ > public AnnotationHolder retrieveAnnotationHolder(Binding binding, boolean forceInitialization) { > if (forceInitialization) > binding.getAnnotationTagBits(); // ensure annotations are up to date >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java >index 55d5b88..21b1c11 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contribution for bug 186342 - [compiler][null] Using annotations for null checking > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.lookup; > >@@ -128,10 +129,14 @@ > long AnnotationSafeVarargs = ASTNode.Bit52L; > /** @since 3.7 - java 7 MethodHandle.invokeExact(..)/invokeGeneric(..)*/ > long AnnotationPolymorphicSignature = ASTNode.Bit53L; >- /** @since 3.8 */ >- long AnnotationPreDestroy = ASTNode.Bit54L; >- /** @since 3.8 */ >- long AnnotationPostConstruct = ASTNode.Bit55L; >+ /** @since 3.8 null annotation for MethodBinding or LocalVariableBinding (argument): */ >+ long AnnotationNullable = ASTNode.Bit56L; >+ /** @since 3.8 null annotation for MethodBinding or LocalVariableBinding (argument): */ >+ long AnnotationNonNull = ASTNode.Bit57L; >+ /** @since 3.8 null-default annotation for PackageBinding or TypeBinding or MethodBinding: */ >+ long AnnotationNonNullByDefault = ASTNode.Bit58L; >+ /** @since 3.8 canceling null-default annotation for PackageBinding or TypeBinding or MethodBinding: */ >+ long AnnotationNullUnspecifiedByDefault = ASTNode.Bit59L; > > long AllStandardAnnotationsMask = > AnnotationTargetMASK >@@ -143,11 +148,13 @@ > | AnnotationSuppressWarnings > | AnnotationSafeVarargs > | AnnotationPolymorphicSignature >- | AnnotationPostConstruct >- | AnnotationPreDestroy; >+ | AnnotationNullable >+ | AnnotationNonNull >+ | AnnotationNonNullByDefault >+ | AnnotationNullUnspecifiedByDefault; > >- long DefaultValueResolved = ASTNode.Bit56L; >+ long DefaultValueResolved = ASTNode.Bit60L; > > // set when type contains non-private constructor(s) >- long HasNonPrivateConstructor = ASTNode.Bit57L; >+ long HasNonPrivateConstructor = ASTNode.Bit61L; > } >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java >index 9a62cc0..e607732 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,6 +7,9 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contributions for >+ * bug 349326 - [1.7] new warning for missing try-with-resources >+ * bug 358903 - Filter practically unimportant resource leak warnings > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.lookup; > >@@ -18,6 +21,7 @@ > char[] LANG = "lang".toCharArray(); //$NON-NLS-1$ > char[] IO = "io".toCharArray(); //$NON-NLS-1$ > char[] UTIL = "util".toCharArray(); //$NON-NLS-1$ >+ char[] ZIP = "zip".toCharArray(); //$NON-NLS-1$ > char[] ANNOTATION = "annotation".toCharArray(); //$NON-NLS-1$ > char[] REFLECT = "reflect".toCharArray(); //$NON-NLS-1$ > char[] LENGTH = "length".toCharArray(); //$NON-NLS-1$ >@@ -123,6 +127,7 @@ > char[][] JAVA_LANG_ANNOTATION_ELEMENTTYPE = {JAVA, LANG, ANNOTATION, "ElementType".toCharArray()}; //$NON-NLS-1$ > char[][] JAVA_LANG_REFLECT_FIELD = new char[][] {JAVA, LANG, REFLECT, "Field".toCharArray()}; //$NON-NLS-1$ > char[][] JAVA_LANG_REFLECT_METHOD = new char[][] {JAVA, LANG, REFLECT, "Method".toCharArray()}; //$NON-NLS-1$ >+ char[][] JAVA_IO_CLOSEABLE = new char[][] { JAVA, IO, "Closeable".toCharArray()};//$NON-NLS-1$ > char[][] JAVA_IO_OBJECTSTREAMEXCEPTION = new char[][] { JAVA, IO, "ObjectStreamException".toCharArray()};//$NON-NLS-1$ > char[][] JAVA_IO_EXTERNALIZABLE = {JAVA, IO, "Externalizable".toCharArray()}; //$NON-NLS-1$ > char[][] JAVA_IO_IOEXCEPTION = new char[][] { JAVA, IO, "IOException".toCharArray()};//$NON-NLS-1$ >@@ -151,6 +156,60 @@ > "MethodHandle$PolymorphicSignature".toCharArray() //$NON-NLS-1$ > }; > char[][] JAVA_LANG_AUTOCLOSEABLE = {JAVA, LANG, "AutoCloseable".toCharArray()}; //$NON-NLS-1$ >+ char[] CLOSE = "close".toCharArray(); //$NON-NLS-1$ >+ // white lists of closeables: >+ char[][] JAVA_IO_WRAPPER_CLOSEABLES = new char[][] { >+ "BufferedInputStream".toCharArray(), //$NON-NLS-1$ >+ "BufferedOutputStream".toCharArray(), //$NON-NLS-1$ >+ "BufferedReader".toCharArray(), //$NON-NLS-1$ >+ "BufferedWriter".toCharArray(), //$NON-NLS-1$ >+ "InputStreamReader".toCharArray(), //$NON-NLS-1$ >+ "PrintWriter".toCharArray(), //$NON-NLS-1$ >+ "LineNumberReader".toCharArray(), //$NON-NLS-1$ >+ "DataInputStream".toCharArray(), //$NON-NLS-1$ >+ "DataOutputStream".toCharArray(), //$NON-NLS-1$ >+ "ObjectInputStream".toCharArray(), //$NON-NLS-1$ >+ "ObjectOutputStream".toCharArray(), //$NON-NLS-1$ >+ "FilterInputStream".toCharArray(), //$NON-NLS-1$ >+ "FilterOutputStream".toCharArray(), //$NON-NLS-1$ >+ "DataInputStream".toCharArray(), //$NON-NLS-1$ >+ "DataOutputStream".toCharArray(), //$NON-NLS-1$ >+ "PushbackInputStream".toCharArray(), //$NON-NLS-1$ >+ "SequenceInputStream".toCharArray(), //$NON-NLS-1$ >+ "PrintStream".toCharArray(), //$NON-NLS-1$ >+ "PushbackReader".toCharArray(), //$NON-NLS-1$ >+ "OutputStreamWriter".toCharArray(), //$NON-NLS-1$ >+ }; >+ char[][] JAVA_UTIL_ZIP_WRAPPER_CLOSEABLES = new char[][] { >+ "GZIPInputStream".toCharArray(), //$NON-NLS-1$ >+ "InflaterInputStream".toCharArray(), //$NON-NLS-1$ >+ "DeflaterInputStream".toCharArray(), //$NON-NLS-1$ >+ "CheckedInputStream".toCharArray(), //$NON-NLS-1$ >+ "ZipInputStream".toCharArray(), //$NON-NLS-1$ >+ "JarInputStream".toCharArray(), //$NON-NLS-1$ >+ "GZIPOutputStream".toCharArray(), //$NON-NLS-1$ >+ "InflaterOutputStream".toCharArray(), //$NON-NLS-1$ >+ "DeflaterOutputStream".toCharArray(), //$NON-NLS-1$ >+ "CheckedOutputStream".toCharArray(), //$NON-NLS-1$ >+ "ZipOutputStream".toCharArray(), //$NON-NLS-1$ >+ "JarOutputStream".toCharArray(), //$NON-NLS-1$ >+ }; >+ char[][][] OTHER_WRAPPER_CLOSEABLES = new char[][][] { >+ {JAVA, "security".toCharArray(), "DigestInputStream".toCharArray()}, //$NON-NLS-1$ //$NON-NLS-2$ >+ {JAVA, "security".toCharArray(), "DigestOutputStream".toCharArray()}, //$NON-NLS-1$ //$NON-NLS-2$ >+ {JAVA, "beans".toCharArray(), "XMLEncoder".toCharArray()}, //$NON-NLS-1$ //$NON-NLS-2$ >+ {JAVA, "beans".toCharArray(), "XMLDecoder".toCharArray()}, //$NON-NLS-1$ //$NON-NLS-2$ >+ {JAVAX, "sound".toCharArray(), "sampled".toCharArray(), "AudioInputStream".toCharArray()}, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ >+ }; >+ char[][] JAVA_IO_RESOURCE_FREE_CLOSEABLES = new char[][] { >+ "StringReader".toCharArray(), //$NON-NLS-1$ >+ "StringWriter".toCharArray(), //$NON-NLS-1$ >+ "ByteArrayInputStream".toCharArray(), //$NON-NLS-1$ >+ "ByteArrayOutputStream".toCharArray(), //$NON-NLS-1$ >+ "CharArrayReader".toCharArray(), //$NON-NLS-1$ >+ "CharArrayWriter".toCharArray(), //$NON-NLS-1$ >+ "StringBufferInputStream".toCharArray(), //$NON-NLS-1$ >+ }; > > // Constraints for generic type argument inference > int CONSTRAINT_EQUAL = 0; // Actual = Formal >@@ -174,18 +233,6 @@ > char[] SYNTHETIC_ACCESS_METHOD_PREFIX = "access$".toCharArray(); //$NON-NLS-1$ > char[] SYNTHETIC_ENUM_CONSTANT_INITIALIZATION_METHOD_PREFIX = " enum constant initialization$".toCharArray(); //$NON-NLS-1$ > char[] SYNTHETIC_STATIC_FACTORY = "<factory>".toCharArray(); //$NON-NLS-1$ >- char[][] JAVAX_ANNOTATION_POSTCONSTRUCT = >- new char[][] { >- JAVAX, >- ANNOTATION, >- "PostConstruct".toCharArray() //$NON-NLS-1$ >- }; >- char[][] JAVAX_ANNOTATION_PREDESTROY = >- new char[][] { >- JAVAX, >- ANNOTATION, >- "PreDestroy".toCharArray() //$NON-NLS-1$ >- }; > > // synthetic package-info name > public static final char[] PACKAGE_INFO_NAME = "package-info".toCharArray(); //$NON-NLS-1$ >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java >index 8e3a647..439b49e 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,6 +7,11 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contributions for >+ * bug 349326 - [1.7] new warning for missing try-with-resources >+ * bug 359362 - FUP of bug 349326: Resource leak on non-Closeable resource >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 358903 - Filter practically unimportant resource leak warnings > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.lookup; > >@@ -96,11 +101,11 @@ > > // java 7 java.lang.AutoCloseable > final int T_JavaLangAutoCloseable = 62; >- >- // new in 3.8 >- final int T_JavaxAnnotationPostConstruct = 63; >- >- final int T_JavaxAnnotationPreDestroy = 64; >+ >+ // new in 3.8 for null annotations: >+ final int T_ConfiguredAnnotationNullable = 65; >+ final int T_ConfiguredAnnotationNonNull = 66; >+ final int T_ConfiguredAnnotationNonNullByDefault = 67; > > final int NoId = Integer.MAX_VALUE; > >@@ -182,4 +187,35 @@ > final int Object2boolean = T_JavaLangObject + (T_boolean << 4); > final int BOXING = 0x200; > final int UNBOXING = 0x400; >+ >+ /** >+ * Marks a type whose type bits have not yet been initialized. >+ * @see ReferenceBinding#hasTypeBit(int) >+ */ >+ final int BitUninitialized = 0x8000000; >+ /** >+ * Marks all sub-types of java.lang.AutoCloseable. >+ * @see ReferenceBinding#hasTypeBit(int) >+ */ >+ final int BitAutoCloseable = 1; >+ /** >+ * Marks all sub-types of java.io.Closeable. >+ * @see ReferenceBinding#hasTypeBit(int) >+ */ >+ final int BitCloseable = 2; >+ /** >+ * Bit for members of a white list: >+ * Subtypes of Closeable that wrap another resource without directly holding any OS resources. >+ */ >+ final int BitWrapperCloseable = 4; >+ /** >+ * Bit for members of a white list: >+ * Subtypes of Closeable that do not hold an OS resource that needs to be released. >+ */ >+ final int BitResourceFreeCloseable = 8; >+ >+ /** >+ * Set of type bits that should be inherited by any sub types. >+ */ >+ final int InheritableBits = BitAutoCloseable | BitCloseable; > } >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java >index 7b6c840..91a7065 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,7 +7,11 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >- * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 282152 - [1.5][compiler] Generics code rejected by Eclipse but accepted by javac >+ * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for >+ * bug 282152 - [1.5][compiler] Generics code rejected by Eclipse but accepted by javac >+ * bug 349326 - [1.7] new warning for missing try-with-resources >+ * bug 359362 - FUP of bug 349326: Resource leak on non-Closeable resource >+ * bug 358903 - Filter practically unimportant resource leak warnings > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.lookup; > >@@ -42,6 +46,7 @@ > this.modifiers = ClassFileConstants.AccPublic | ExtraCompilerModifiers.AccGenericSignature; // treat type var as public > this.tagBits |= TagBits.HasTypeVariable; > this.environment = environment; >+ this.typeBits = TypeIds.BitUninitialized; > } > > /** >@@ -307,6 +312,20 @@ > return true; > } > >+ public boolean hasTypeBit(int bit) { >+ if (this.typeBits == TypeIds.BitUninitialized) { >+ // initialize from bounds >+ this.typeBits = 0; >+ if (this.superclass != null && this.superclass.hasTypeBit(~TypeIds.BitUninitialized)) >+ this.typeBits |= (this.superclass.typeBits & TypeIds.InheritableBits); >+ if (this.superInterfaces != null) >+ for (int i = 0, l = this.superInterfaces.length; i < l; i++) >+ if (this.superInterfaces[i].hasTypeBit(~TypeIds.BitUninitialized)) >+ this.typeBits |= (this.superInterfaces[i].typeBits & TypeIds.InheritableBits); >+ } >+ return (this.typeBits & bit) != 0; >+ } >+ > /** > * Returns true if the type variable is directly bound to a given type > */ >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java >index 0ca15de..2da4984 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2008 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.lookup; > >@@ -41,6 +42,10 @@ > public String debugName() { > return toString(); > } >+public boolean hasTypeBit(int bit) { >+ // shouldn't happen since we are not called before analyseCode(), but play safe: >+ return false; >+} > ReferenceBinding resolve(LookupEnvironment environment, boolean convertGenericToRawType) { > ReferenceBinding targetType = this.resolvedType; > if (targetType == null) { >@@ -50,7 +55,7 @@ > } > if (targetType == null || targetType == this) { // could not resolve any better, error was already reported against it > // report the missing class file first - only if not resolving a previously missing type >- if ((this.tagBits & TagBits.HasMissingType) == 0) { >+ if ((this.tagBits & TagBits.HasMissingType) == 0 && !environment.mayTolerateMissingType) { > environment.problemReporter.isClassPathCorrect( > this.compoundName, > environment.unitBeingCompleted, >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java >index 0e6e487..93dffe1 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2005, 2009 IBM Corporation and others. >+ * Copyright (c) 2005, 2012 IBM Corporation 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 >@@ -7,6 +7,10 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contribution for >+ * bug 349326 - [1.7] new warning for missing try-with-resources >+ * bug 359362 - FUP of bug 349326: Resource leak on non-Closeable resource >+ * bug 358903 - Filter practically unimportant resource leak warnings > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.lookup; > >@@ -54,6 +58,7 @@ > if (bound instanceof UnresolvedReferenceBinding) > ((UnresolvedReferenceBinding) bound).addWrapper(this, environment); > this.tagBits |= TagBits.HasUnresolvedTypeVariables; // cleared in resolve() >+ this.typeBits = TypeIds.BitUninitialized; > } > > public int kind() { >@@ -420,6 +425,20 @@ > return this.genericType.hashCode(); > } > >+ public boolean hasTypeBit(int bit) { >+ if (this.typeBits == TypeIds.BitUninitialized) { >+ // initialize from upper bounds >+ this.typeBits = 0; >+ if (this.superclass != null && this.superclass.hasTypeBit(~TypeIds.BitUninitialized)) >+ this.typeBits |= (this.superclass.typeBits & TypeIds.InheritableBits); >+ if (this.superInterfaces != null) >+ for (int i = 0, l = this.superInterfaces.length; i < l; i++) >+ if (this.superInterfaces[i].hasTypeBit(~TypeIds.BitUninitialized)) >+ this.typeBits |= (this.superInterfaces[i].typeBits & TypeIds.InheritableBits); >+ } >+ return (this.typeBits & bit) != 0; >+ } >+ > void initialize(ReferenceBinding someGenericType, TypeBinding someBound, TypeBinding[] someOtherBounds) { > this.genericType = someGenericType; > this.bound = someBound; >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java >index ba7d9a0..6718cb3 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java >@@ -1354,9 +1354,10 @@ > idx++; > while (this.source[idx] == 'u') > idx++; >- if (!(((c1 = ScannerHelper.getNumericValue(this.source[idx++])) > 15 || c1 < 0) >- || ((c2 = ScannerHelper.getNumericValue(this.source[idx++])) > 15 || c2 < 0) >- || ((c3 = ScannerHelper.getNumericValue(this.source[idx++])) > 15 || c3 < 0) || ((c4 = ScannerHelper.getNumericValue(this.source[idx++])) > 15 || c4 < 0))) { >+ if (!(((c1 = ScannerHelper.getHexadecimalValue(this.source[idx++])) > 15 || c1 < 0) >+ || ((c2 = ScannerHelper.getHexadecimalValue(this.source[idx++])) > 15 || c2 < 0) >+ || ((c3 = ScannerHelper.getHexadecimalValue(this.source[idx++])) > 15 || c3 < 0) >+ || ((c4 = ScannerHelper.getHexadecimalValue(this.source[idx++])) > 15 || c4 < 0))) { > c = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4); > } > } >@@ -1473,9 +1474,10 @@ > this.index++; > while (this.source[this.index] == 'u') > this.index++; >- if (!(((c1 = ScannerHelper.getNumericValue(this.source[this.index++])) > 15 || c1 < 0) >- || ((c2 = ScannerHelper.getNumericValue(this.source[this.index++])) > 15 || c2 < 0) >- || ((c3 = ScannerHelper.getNumericValue(this.source[this.index++])) > 15 || c3 < 0) || ((c4 = ScannerHelper.getNumericValue(this.source[this.index++])) > 15 || c4 < 0))) { >+ if (!(((c1 = ScannerHelper.getHexadecimalValue(this.source[this.index++])) > 15 || c1 < 0) >+ || ((c2 = ScannerHelper.getHexadecimalValue(this.source[this.index++])) > 15 || c2 < 0) >+ || ((c3 = ScannerHelper.getHexadecimalValue(this.source[this.index++])) > 15 || c3 < 0) >+ || ((c4 = ScannerHelper.getHexadecimalValue(this.source[this.index++])) > 15 || c4 < 0))) { > c = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4); > } else { > // TODO (frederic) currently reset to previous position, perhaps signal a syntax error would be more appropriate >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java >index b729329..699af71 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java >@@ -385,9 +385,10 @@ > this.index++; > while (this.source[this.index] == 'u') > this.index++; >- if (!(((c1 = ScannerHelper.getNumericValue(this.source[this.index++])) > 15 || c1 < 0) >- || ((c2 = ScannerHelper.getNumericValue(this.source[this.index++])) > 15 || c2 < 0) >- || ((c3 = ScannerHelper.getNumericValue(this.source[this.index++])) > 15 || c3 < 0) || ((c4 = ScannerHelper.getNumericValue(this.source[this.index++])) > 15 || c4 < 0))) { >+ if (!(((c1 = ScannerHelper.getHexadecimalValue(this.source[this.index++])) > 15 || c1 < 0) >+ || ((c2 = ScannerHelper.getHexadecimalValue(this.source[this.index++])) > 15 || c2 < 0) >+ || ((c3 = ScannerHelper.getHexadecimalValue(this.source[this.index++])) > 15 || c3 < 0) >+ || ((c4 = ScannerHelper.getHexadecimalValue(this.source[this.index++])) > 15 || c4 < 0))) { > first = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4); > } else { > this.index = pos; >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java >index 741e8fa..53b4f51 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -8,6 +8,7 @@ > * Contributors: > * IBM Corporation - initial API and implementation > * Tom Tromey - patch for readTable(String) as described in http://bugs.eclipse.org/bugs/show_bug.cgi?id=32196 >+ * Stephan Herrmann - Contribution for Bug 366003 - CCE in ASTNode.resolveAnnotations(ASTNode.java:639) > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.parser; > >@@ -868,6 +869,7 @@ > // used for recovery > protected int lastJavadocEnd; > public org.eclipse.jdt.internal.compiler.ReadManager readManager; >+private boolean shouldDeferRecovery = false; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=291040 > > public Parser(ProblemReporter problemReporter, boolean optimizeStringLiterals) { > >@@ -2262,6 +2264,7 @@ > // ClassBodyopt ::= $empty > pushOnAstStack(null); > this.endPosition = this.rParenPos; >+ this.shouldDeferRecovery = false; > } > protected void consumeClassDeclaration() { > // ClassDeclaration ::= ClassHeader ClassBody >@@ -2993,13 +2996,13 @@ > pos--; > } > if (source[pos] == '\\' && >- !((c1 = ScannerHelper.getNumericValue(source[this.endStatementPosition - 3])) > 15 >+ !((c1 = ScannerHelper.getHexadecimalValue(source[this.endStatementPosition - 3])) > 15 > || c1 < 0 >- || (c2 = ScannerHelper.getNumericValue(source[this.endStatementPosition - 2])) > 15 >+ || (c2 = ScannerHelper.getHexadecimalValue(source[this.endStatementPosition - 2])) > 15 > || c2 < 0 >- || (c3 = ScannerHelper.getNumericValue(source[this.endStatementPosition - 1])) > 15 >+ || (c3 = ScannerHelper.getHexadecimalValue(source[this.endStatementPosition - 1])) > 15 > || c3 < 0 >- || (c4 = ScannerHelper.getNumericValue(source[this.endStatementPosition])) > 15 >+ || (c4 = ScannerHelper.getHexadecimalValue(source[this.endStatementPosition])) > 15 > || c4 < 0) && > ((char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4)) == ';'){ > // we have a Unicode for the ';' (/u003B) >@@ -3104,6 +3107,7 @@ > iteratorForStatement.sourceEnd = localDeclaration.declarationSourceEnd; > } > protected void consumeEnterAnonymousClassBody(boolean qualified) { >+ this.shouldDeferRecovery = false; > // EnterAnonymousClassBody ::= $empty > TypeReference typeReference = getTypeReference(0); > >@@ -3943,6 +3947,9 @@ > arg.annotations = new Annotation[length], > 0, > length); >+ RecoveredType currentRecoveryType = this.currentRecoveryType(); >+ if (currentRecoveryType != null) >+ currentRecoveryType.annotationsConsumed(arg.annotations); > } > pushOnAstStack(arg); > >@@ -5310,1748 +5317,1755 @@ > // PushRPAREN ::= ')' > pushOnIntStack(this.rParenPos); > } >-// This method is part of an automatic generation : do NOT edit-modify >-protected void consumeRule(int act) { >- switch ( act ) { >- case 30 : if (DEBUG) { System.out.println("Type ::= PrimitiveType"); } //$NON-NLS-1$ >- consumePrimitiveType(); >- break; >- >- case 44 : if (DEBUG) { System.out.println("ReferenceType ::= ClassOrInterfaceType"); } //$NON-NLS-1$ >- consumeReferenceType(); >- break; >- >- case 48 : if (DEBUG) { System.out.println("ClassOrInterface ::= Name"); } //$NON-NLS-1$ >- consumeClassOrInterfaceName(); >- break; >- >- case 49 : if (DEBUG) { System.out.println("ClassOrInterface ::= GenericType DOT Name"); } //$NON-NLS-1$ >- consumeClassOrInterface(); >- break; >- >- case 50 : if (DEBUG) { System.out.println("GenericType ::= ClassOrInterface TypeArguments"); } //$NON-NLS-1$ >- consumeGenericType(); >- break; >- >- case 51 : if (DEBUG) { System.out.println("GenericType ::= ClassOrInterface LESS GREATER"); } //$NON-NLS-1$ >- consumeGenericTypeWithDiamond(); >- break; >- >- case 52 : if (DEBUG) { System.out.println("ArrayTypeWithTypeArgumentsName ::= GenericType DOT Name"); } //$NON-NLS-1$ >- consumeArrayTypeWithTypeArgumentsName(); >- break; >- >- case 53 : if (DEBUG) { System.out.println("ArrayType ::= PrimitiveType Dims"); } //$NON-NLS-1$ >- consumePrimitiveArrayType(); >- break; >- >- case 54 : if (DEBUG) { System.out.println("ArrayType ::= Name Dims"); } //$NON-NLS-1$ >- consumeNameArrayType(); >- break; >- >- case 55 : if (DEBUG) { System.out.println("ArrayType ::= ArrayTypeWithTypeArgumentsName Dims"); } //$NON-NLS-1$ >- consumeGenericTypeNameArrayType(); >- break; >- >- case 56 : if (DEBUG) { System.out.println("ArrayType ::= GenericType Dims"); } //$NON-NLS-1$ >- consumeGenericTypeArrayType(); >- break; >- >- case 61 : if (DEBUG) { System.out.println("QualifiedName ::= Name DOT SimpleName"); } //$NON-NLS-1$ >- consumeQualifiedName(); >- break; >- >- case 62 : if (DEBUG) { System.out.println("CompilationUnit ::= EnterCompilationUnit..."); } //$NON-NLS-1$ >- consumeCompilationUnit(); >- break; >- >- case 63 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= PackageDeclaration"); } //$NON-NLS-1$ >- consumeInternalCompilationUnit(); >- break; >- >- case 64 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= PackageDeclaration..."); } //$NON-NLS-1$ >- consumeInternalCompilationUnit(); >- break; >- >- case 65 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= PackageDeclaration..."); } //$NON-NLS-1$ >- consumeInternalCompilationUnitWithTypes(); >- break; >- >- case 66 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= PackageDeclaration..."); } //$NON-NLS-1$ >- consumeInternalCompilationUnitWithTypes(); >- break; >- >- case 67 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= ImportDeclarations..."); } //$NON-NLS-1$ >- consumeInternalCompilationUnit(); >- break; >- >- case 68 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= TypeDeclarations"); } //$NON-NLS-1$ >- consumeInternalCompilationUnitWithTypes(); >- break; >- >- case 69 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= ImportDeclarations..."); } //$NON-NLS-1$ >- consumeInternalCompilationUnitWithTypes(); >- break; >- >- case 70 : if (DEBUG) { System.out.println("InternalCompilationUnit ::="); } //$NON-NLS-1$ >- consumeEmptyInternalCompilationUnit(); >- break; >- >- case 71 : if (DEBUG) { System.out.println("ReduceImports ::="); } //$NON-NLS-1$ >- consumeReduceImports(); >- break; >- >- case 72 : if (DEBUG) { System.out.println("EnterCompilationUnit ::="); } //$NON-NLS-1$ >- consumeEnterCompilationUnit(); >- break; >- >- case 88 : if (DEBUG) { System.out.println("CatchHeader ::= catch LPAREN CatchFormalParameter RPAREN"); } //$NON-NLS-1$ >- consumeCatchHeader(); >- break; >- >- case 90 : if (DEBUG) { System.out.println("ImportDeclarations ::= ImportDeclarations..."); } //$NON-NLS-1$ >- consumeImportDeclarations(); >- break; >- >- case 92 : if (DEBUG) { System.out.println("TypeDeclarations ::= TypeDeclarations TypeDeclaration"); } //$NON-NLS-1$ >- consumeTypeDeclarations(); >- break; >- >- case 93 : if (DEBUG) { System.out.println("PackageDeclaration ::= PackageDeclarationName SEMICOLON"); } //$NON-NLS-1$ >- consumePackageDeclaration(); >- break; >- >- case 94 : if (DEBUG) { System.out.println("PackageDeclarationName ::= Modifiers package..."); } //$NON-NLS-1$ >- consumePackageDeclarationNameWithModifiers(); >- break; >- >- case 95 : if (DEBUG) { System.out.println("PackageDeclarationName ::= PackageComment package Name"); } //$NON-NLS-1$ >- consumePackageDeclarationName(); >- break; >- >- case 96 : if (DEBUG) { System.out.println("PackageComment ::="); } //$NON-NLS-1$ >- consumePackageComment(); >- break; >- >- case 101 : if (DEBUG) { System.out.println("SingleTypeImportDeclaration ::=..."); } //$NON-NLS-1$ >- consumeImportDeclaration(); >- break; >- >- case 102 : if (DEBUG) { System.out.println("SingleTypeImportDeclarationName ::= import Name"); } //$NON-NLS-1$ >- consumeSingleTypeImportDeclarationName(); >- break; >- >- case 103 : if (DEBUG) { System.out.println("TypeImportOnDemandDeclaration ::=..."); } //$NON-NLS-1$ >- consumeImportDeclaration(); >- break; >- >- case 104 : if (DEBUG) { System.out.println("TypeImportOnDemandDeclarationName ::= import Name DOT..."); } //$NON-NLS-1$ >- consumeTypeImportOnDemandDeclarationName(); >- break; >- >- case 107 : if (DEBUG) { System.out.println("TypeDeclaration ::= SEMICOLON"); } //$NON-NLS-1$ >- consumeEmptyTypeDeclaration(); >- break; >- >- case 111 : if (DEBUG) { System.out.println("Modifiers ::= Modifiers Modifier"); } //$NON-NLS-1$ >- consumeModifiers2(); >- break; >- >- case 123 : if (DEBUG) { System.out.println("Modifier ::= Annotation"); } //$NON-NLS-1$ >- consumeAnnotationAsModifier(); >- break; >- >- case 124 : if (DEBUG) { System.out.println("ClassDeclaration ::= ClassHeader ClassBody"); } //$NON-NLS-1$ >- consumeClassDeclaration(); >- break; >- >- case 125 : if (DEBUG) { System.out.println("ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt..."); } //$NON-NLS-1$ >- consumeClassHeader(); >- break; >- >- case 126 : if (DEBUG) { System.out.println("ClassHeaderName ::= ClassHeaderName1 TypeParameters"); } //$NON-NLS-1$ >- consumeTypeHeaderNameWithTypeParameters(); >- break; >- >- case 128 : if (DEBUG) { System.out.println("ClassHeaderName1 ::= Modifiersopt class Identifier"); } //$NON-NLS-1$ >- consumeClassHeaderName1(); >- break; >- >- case 129 : if (DEBUG) { System.out.println("ClassHeaderExtends ::= extends ClassType"); } //$NON-NLS-1$ >- consumeClassHeaderExtends(); >- break; >- >- case 130 : if (DEBUG) { System.out.println("ClassHeaderImplements ::= implements InterfaceTypeList"); } //$NON-NLS-1$ >- consumeClassHeaderImplements(); >- break; >- >- case 132 : if (DEBUG) { System.out.println("InterfaceTypeList ::= InterfaceTypeList COMMA..."); } //$NON-NLS-1$ >- consumeInterfaceTypeList(); >- break; >- >- case 133 : if (DEBUG) { System.out.println("InterfaceType ::= ClassOrInterfaceType"); } //$NON-NLS-1$ >- consumeInterfaceType(); >- break; >- >- case 136 : if (DEBUG) { System.out.println("ClassBodyDeclarations ::= ClassBodyDeclarations..."); } //$NON-NLS-1$ >- consumeClassBodyDeclarations(); >- break; >- >- case 140 : if (DEBUG) { System.out.println("ClassBodyDeclaration ::= Diet NestedMethod..."); } //$NON-NLS-1$ >- consumeClassBodyDeclaration(); >- break; >- >- case 141 : if (DEBUG) { System.out.println("Diet ::="); } //$NON-NLS-1$ >- consumeDiet(); >- break; >- >- case 142 : if (DEBUG) { System.out.println("Initializer ::= Diet NestedMethod CreateInitializer..."); } //$NON-NLS-1$ >- consumeClassBodyDeclaration(); >- break; >- >- case 143 : if (DEBUG) { System.out.println("CreateInitializer ::="); } //$NON-NLS-1$ >- consumeCreateInitializer(); >- break; >- >- case 150 : if (DEBUG) { System.out.println("ClassMemberDeclaration ::= SEMICOLON"); } //$NON-NLS-1$ >- consumeEmptyTypeDeclaration(); >- break; >- >- case 153 : if (DEBUG) { System.out.println("FieldDeclaration ::= Modifiersopt Type..."); } //$NON-NLS-1$ >- consumeFieldDeclaration(); >- break; >- >- case 155 : if (DEBUG) { System.out.println("VariableDeclarators ::= VariableDeclarators COMMA..."); } //$NON-NLS-1$ >- consumeVariableDeclarators(); >- break; >- >- case 158 : if (DEBUG) { System.out.println("EnterVariable ::="); } //$NON-NLS-1$ >- consumeEnterVariable(); >- break; >- >- case 159 : if (DEBUG) { System.out.println("ExitVariableWithInitialization ::="); } //$NON-NLS-1$ >- consumeExitVariableWithInitialization(); >- break; >- >- case 160 : if (DEBUG) { System.out.println("ExitVariableWithoutInitialization ::="); } //$NON-NLS-1$ >- consumeExitVariableWithoutInitialization(); >- break; >- >- case 161 : if (DEBUG) { System.out.println("ForceNoDiet ::="); } //$NON-NLS-1$ >- consumeForceNoDiet(); >- break; >- >- case 162 : if (DEBUG) { System.out.println("RestoreDiet ::="); } //$NON-NLS-1$ >- consumeRestoreDiet(); >- break; >- >- case 167 : if (DEBUG) { System.out.println("MethodDeclaration ::= MethodHeader MethodBody"); } //$NON-NLS-1$ >- // set to true to consume a method with a body >- consumeMethodDeclaration(true); >- break; >- >- case 168 : if (DEBUG) { System.out.println("AbstractMethodDeclaration ::= MethodHeader SEMICOLON"); } //$NON-NLS-1$ >- // set to false to consume a method without body >- consumeMethodDeclaration(false); >- break; >- >- case 169 : if (DEBUG) { System.out.println("MethodHeader ::= MethodHeaderName FormalParameterListopt"); } //$NON-NLS-1$ >- consumeMethodHeader(); >- break; >- >- case 170 : if (DEBUG) { System.out.println("MethodHeaderName ::= Modifiersopt TypeParameters Type..."); } //$NON-NLS-1$ >- consumeMethodHeaderNameWithTypeParameters(false); >- break; >- >- case 171 : if (DEBUG) { System.out.println("MethodHeaderName ::= Modifiersopt Type Identifier LPAREN"); } //$NON-NLS-1$ >- consumeMethodHeaderName(false); >- break; >- >- case 172 : if (DEBUG) { System.out.println("MethodHeaderRightParen ::= RPAREN"); } //$NON-NLS-1$ >- consumeMethodHeaderRightParen(); >- break; >- >- case 173 : if (DEBUG) { System.out.println("MethodHeaderExtendedDims ::= Dimsopt"); } //$NON-NLS-1$ >- consumeMethodHeaderExtendedDims(); >- break; >- >- case 174 : if (DEBUG) { System.out.println("MethodHeaderThrowsClause ::= throws ClassTypeList"); } //$NON-NLS-1$ >- consumeMethodHeaderThrowsClause(); >- break; >- >- case 175 : if (DEBUG) { System.out.println("ConstructorHeader ::= ConstructorHeaderName..."); } //$NON-NLS-1$ >- consumeConstructorHeader(); >- break; >- >- case 176 : if (DEBUG) { System.out.println("ConstructorHeaderName ::= Modifiersopt TypeParameters..."); } //$NON-NLS-1$ >- consumeConstructorHeaderNameWithTypeParameters(); >- break; >- >- case 177 : if (DEBUG) { System.out.println("ConstructorHeaderName ::= Modifiersopt Identifier LPAREN"); } //$NON-NLS-1$ >- consumeConstructorHeaderName(); >- break; >- >- case 179 : if (DEBUG) { System.out.println("FormalParameterList ::= FormalParameterList COMMA..."); } //$NON-NLS-1$ >- consumeFormalParameterList(); >- break; >- >- case 180 : if (DEBUG) { System.out.println("FormalParameter ::= Modifiersopt Type..."); } //$NON-NLS-1$ >- consumeFormalParameter(false); >- break; >- >- case 181 : if (DEBUG) { System.out.println("FormalParameter ::= Modifiersopt Type ELLIPSIS..."); } //$NON-NLS-1$ >- consumeFormalParameter(true); >- break; >- >- case 182 : if (DEBUG) { System.out.println("CatchFormalParameter ::= Modifiersopt CatchType..."); } //$NON-NLS-1$ >- consumeCatchFormalParameter(); >- break; >- >- case 183 : if (DEBUG) { System.out.println("CatchType ::= UnionType"); } //$NON-NLS-1$ >- consumeCatchType(); >- break; >- >- case 184 : if (DEBUG) { System.out.println("UnionType ::= Type"); } //$NON-NLS-1$ >- consumeUnionTypeAsClassType(); >- break; >- >- case 185 : if (DEBUG) { System.out.println("UnionType ::= UnionType OR Type"); } //$NON-NLS-1$ >- consumeUnionType(); >- break; >- >- case 187 : if (DEBUG) { System.out.println("ClassTypeList ::= ClassTypeList COMMA ClassTypeElt"); } //$NON-NLS-1$ >- consumeClassTypeList(); >- break; >- >- case 188 : if (DEBUG) { System.out.println("ClassTypeElt ::= ClassType"); } //$NON-NLS-1$ >- consumeClassTypeElt(); >- break; >- >- case 189 : if (DEBUG) { System.out.println("MethodBody ::= NestedMethod LBRACE BlockStatementsopt..."); } //$NON-NLS-1$ >- consumeMethodBody(); >- break; >- >- case 190 : if (DEBUG) { System.out.println("NestedMethod ::="); } //$NON-NLS-1$ >- consumeNestedMethod(); >- break; >- >- case 191 : if (DEBUG) { System.out.println("StaticInitializer ::= StaticOnly Block"); } //$NON-NLS-1$ >- consumeStaticInitializer(); >- break; >- >- case 192 : if (DEBUG) { System.out.println("StaticOnly ::= static"); } //$NON-NLS-1$ >- consumeStaticOnly(); >- break; >- >- case 193 : if (DEBUG) { System.out.println("ConstructorDeclaration ::= ConstructorHeader MethodBody"); } //$NON-NLS-1$ >- consumeConstructorDeclaration() ; >- break; >- >- case 194 : if (DEBUG) { System.out.println("ConstructorDeclaration ::= ConstructorHeader SEMICOLON"); } //$NON-NLS-1$ >- consumeInvalidConstructorDeclaration() ; >- break; >- >- case 195 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= this LPAREN..."); } //$NON-NLS-1$ >- consumeExplicitConstructorInvocation(0, THIS_CALL); >- break; >- >- case 196 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= OnlyTypeArguments this"); } //$NON-NLS-1$ >- consumeExplicitConstructorInvocationWithTypeArguments(0,THIS_CALL); >- break; >- >- case 197 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= super LPAREN..."); } //$NON-NLS-1$ >- consumeExplicitConstructorInvocation(0,SUPER_CALL); >- break; >- >- case 198 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= OnlyTypeArguments..."); } //$NON-NLS-1$ >- consumeExplicitConstructorInvocationWithTypeArguments(0,SUPER_CALL); >- break; >- >- case 199 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Primary DOT super..."); } //$NON-NLS-1$ >- consumeExplicitConstructorInvocation(1, SUPER_CALL); >- break; >- >- case 200 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Primary DOT..."); } //$NON-NLS-1$ >- consumeExplicitConstructorInvocationWithTypeArguments(1, SUPER_CALL); >- break; >- >- case 201 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT super LPAREN"); } //$NON-NLS-1$ >- consumeExplicitConstructorInvocation(2, SUPER_CALL); >- break; >- >- case 202 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT..."); } //$NON-NLS-1$ >- consumeExplicitConstructorInvocationWithTypeArguments(2, SUPER_CALL); >- break; >- >- case 203 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Primary DOT this..."); } //$NON-NLS-1$ >- consumeExplicitConstructorInvocation(1, THIS_CALL); >- break; >- >- case 204 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Primary DOT..."); } //$NON-NLS-1$ >- consumeExplicitConstructorInvocationWithTypeArguments(1, THIS_CALL); >- break; >- >- case 205 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT this LPAREN"); } //$NON-NLS-1$ >- consumeExplicitConstructorInvocation(2, THIS_CALL); >- break; >- >- case 206 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT..."); } //$NON-NLS-1$ >- consumeExplicitConstructorInvocationWithTypeArguments(2, THIS_CALL); >- break; >- >- case 207 : if (DEBUG) { System.out.println("InterfaceDeclaration ::= InterfaceHeader InterfaceBody"); } //$NON-NLS-1$ >- consumeInterfaceDeclaration(); >- break; >- >- case 208 : if (DEBUG) { System.out.println("InterfaceHeader ::= InterfaceHeaderName..."); } //$NON-NLS-1$ >- consumeInterfaceHeader(); >- break; >- >- case 209 : if (DEBUG) { System.out.println("InterfaceHeaderName ::= InterfaceHeaderName1..."); } //$NON-NLS-1$ >- consumeTypeHeaderNameWithTypeParameters(); >- break; >- >- case 211 : if (DEBUG) { System.out.println("InterfaceHeaderName1 ::= Modifiersopt interface..."); } //$NON-NLS-1$ >- consumeInterfaceHeaderName1(); >- break; >- >- case 212 : if (DEBUG) { System.out.println("InterfaceHeaderExtends ::= extends InterfaceTypeList"); } //$NON-NLS-1$ >- consumeInterfaceHeaderExtends(); >- break; >- >- case 215 : if (DEBUG) { System.out.println("InterfaceMemberDeclarations ::=..."); } //$NON-NLS-1$ >- consumeInterfaceMemberDeclarations(); >- break; >- >- case 216 : if (DEBUG) { System.out.println("InterfaceMemberDeclaration ::= SEMICOLON"); } //$NON-NLS-1$ >- consumeEmptyTypeDeclaration(); >- break; >- >- case 218 : if (DEBUG) { System.out.println("InterfaceMemberDeclaration ::= MethodHeader MethodBody"); } //$NON-NLS-1$ >- consumeInvalidMethodDeclaration(); >- break; >- >- case 219 : if (DEBUG) { System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader..."); } //$NON-NLS-1$ >- consumeInvalidConstructorDeclaration(true); >- break; >- >- case 220 : if (DEBUG) { System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader..."); } //$NON-NLS-1$ >- consumeInvalidConstructorDeclaration(false); >- break; >- >- case 231 : if (DEBUG) { System.out.println("PushLeftBrace ::="); } //$NON-NLS-1$ >- consumePushLeftBrace(); >- break; >- >- case 232 : if (DEBUG) { System.out.println("ArrayInitializer ::= LBRACE PushLeftBrace ,opt RBRACE"); } //$NON-NLS-1$ >- consumeEmptyArrayInitializer(); >- break; >- >- case 233 : if (DEBUG) { System.out.println("ArrayInitializer ::= LBRACE PushLeftBrace..."); } //$NON-NLS-1$ >- consumeArrayInitializer(); >- break; >- >- case 234 : if (DEBUG) { System.out.println("ArrayInitializer ::= LBRACE PushLeftBrace..."); } //$NON-NLS-1$ >- consumeArrayInitializer(); >- break; >- >- case 236 : if (DEBUG) { System.out.println("VariableInitializers ::= VariableInitializers COMMA..."); } //$NON-NLS-1$ >- consumeVariableInitializers(); >- break; >- >- case 237 : if (DEBUG) { System.out.println("Block ::= OpenBlock LBRACE BlockStatementsopt RBRACE"); } //$NON-NLS-1$ >- consumeBlock(); >- break; >- >- case 238 : if (DEBUG) { System.out.println("OpenBlock ::="); } //$NON-NLS-1$ >- consumeOpenBlock() ; >- break; >- >- case 240 : if (DEBUG) { System.out.println("BlockStatements ::= BlockStatements BlockStatement"); } //$NON-NLS-1$ >- consumeBlockStatements() ; >- break; >- >- case 244 : if (DEBUG) { System.out.println("BlockStatement ::= InterfaceDeclaration"); } //$NON-NLS-1$ >- consumeInvalidInterfaceDeclaration(); >- break; >- >- case 245 : if (DEBUG) { System.out.println("BlockStatement ::= AnnotationTypeDeclaration"); } //$NON-NLS-1$ >- consumeInvalidAnnotationTypeDeclaration(); >- break; >- >- case 246 : if (DEBUG) { System.out.println("BlockStatement ::= EnumDeclaration"); } //$NON-NLS-1$ >- consumeInvalidEnumDeclaration(); >- break; >- >- case 247 : if (DEBUG) { System.out.println("LocalVariableDeclarationStatement ::=..."); } //$NON-NLS-1$ >- consumeLocalVariableDeclarationStatement(); >- break; >- >- case 248 : if (DEBUG) { System.out.println("LocalVariableDeclaration ::= Type PushModifiers..."); } //$NON-NLS-1$ >- consumeLocalVariableDeclaration(); >- break; >- >- case 249 : if (DEBUG) { System.out.println("LocalVariableDeclaration ::= Modifiers Type..."); } //$NON-NLS-1$ >- consumeLocalVariableDeclaration(); >- break; >- >- case 250 : if (DEBUG) { System.out.println("PushModifiers ::="); } //$NON-NLS-1$ >- consumePushModifiers(); >- break; >- >- case 251 : if (DEBUG) { System.out.println("PushModifiersForHeader ::="); } //$NON-NLS-1$ >- consumePushModifiersForHeader(); >- break; >- >- case 252 : if (DEBUG) { System.out.println("PushRealModifiers ::="); } //$NON-NLS-1$ >- consumePushRealModifiers(); >- break; >- >- case 279 : if (DEBUG) { System.out.println("EmptyStatement ::= SEMICOLON"); } //$NON-NLS-1$ >- consumeEmptyStatement(); >- break; >- >- case 280 : if (DEBUG) { System.out.println("LabeledStatement ::= Label COLON Statement"); } //$NON-NLS-1$ >- consumeStatementLabel() ; >- break; >- >- case 281 : if (DEBUG) { System.out.println("LabeledStatementNoShortIf ::= Label COLON..."); } //$NON-NLS-1$ >- consumeStatementLabel() ; >- break; >- >- case 282 : if (DEBUG) { System.out.println("Label ::= Identifier"); } //$NON-NLS-1$ >- consumeLabel() ; >- break; >- >- case 283 : if (DEBUG) { System.out.println("ExpressionStatement ::= StatementExpression SEMICOLON"); } //$NON-NLS-1$ >- consumeExpressionStatement(); >- break; >- >- case 292 : if (DEBUG) { System.out.println("IfThenStatement ::= if LPAREN Expression RPAREN..."); } //$NON-NLS-1$ >- consumeStatementIfNoElse(); >- break; >- >- case 293 : if (DEBUG) { System.out.println("IfThenElseStatement ::= if LPAREN Expression RPAREN..."); } //$NON-NLS-1$ >- consumeStatementIfWithElse(); >- break; >- >- case 294 : if (DEBUG) { System.out.println("IfThenElseStatementNoShortIf ::= if LPAREN Expression..."); } //$NON-NLS-1$ >- consumeStatementIfWithElse(); >- break; >- >- case 295 : if (DEBUG) { System.out.println("SwitchStatement ::= switch LPAREN Expression RPAREN..."); } //$NON-NLS-1$ >- consumeStatementSwitch() ; >- break; >- >- case 296 : if (DEBUG) { System.out.println("SwitchBlock ::= LBRACE RBRACE"); } //$NON-NLS-1$ >- consumeEmptySwitchBlock() ; >- break; >- >- case 299 : if (DEBUG) { System.out.println("SwitchBlock ::= LBRACE SwitchBlockStatements..."); } //$NON-NLS-1$ >- consumeSwitchBlock() ; >- break; >- >- case 301 : if (DEBUG) { System.out.println("SwitchBlockStatements ::= SwitchBlockStatements..."); } //$NON-NLS-1$ >- consumeSwitchBlockStatements() ; >- break; >- >- case 302 : if (DEBUG) { System.out.println("SwitchBlockStatement ::= SwitchLabels BlockStatements"); } //$NON-NLS-1$ >- consumeSwitchBlockStatement() ; >- break; >- >- case 304 : if (DEBUG) { System.out.println("SwitchLabels ::= SwitchLabels SwitchLabel"); } //$NON-NLS-1$ >- consumeSwitchLabels() ; >- break; >- >- case 305 : if (DEBUG) { System.out.println("SwitchLabel ::= case ConstantExpression COLON"); } //$NON-NLS-1$ >- consumeCaseLabel(); >- break; >- >- case 306 : if (DEBUG) { System.out.println("SwitchLabel ::= default COLON"); } //$NON-NLS-1$ >- consumeDefaultLabel(); >- break; >- >- case 307 : if (DEBUG) { System.out.println("WhileStatement ::= while LPAREN Expression RPAREN..."); } //$NON-NLS-1$ >- consumeStatementWhile() ; >- break; >- >- case 308 : if (DEBUG) { System.out.println("WhileStatementNoShortIf ::= while LPAREN Expression..."); } //$NON-NLS-1$ >- consumeStatementWhile() ; >- break; >- >- case 309 : if (DEBUG) { System.out.println("DoStatement ::= do Statement while LPAREN Expression..."); } //$NON-NLS-1$ >- consumeStatementDo() ; >- break; >- >- case 310 : if (DEBUG) { System.out.println("ForStatement ::= for LPAREN ForInitopt SEMICOLON..."); } //$NON-NLS-1$ >- consumeStatementFor() ; >- break; >- >- case 311 : if (DEBUG) { System.out.println("ForStatementNoShortIf ::= for LPAREN ForInitopt..."); } //$NON-NLS-1$ >- consumeStatementFor() ; >- break; >- >- case 312 : if (DEBUG) { System.out.println("ForInit ::= StatementExpressionList"); } //$NON-NLS-1$ >- consumeForInit() ; >- break; >- >- case 316 : if (DEBUG) { System.out.println("StatementExpressionList ::= StatementExpressionList..."); } //$NON-NLS-1$ >- consumeStatementExpressionList() ; >- break; >- >- case 317 : if (DEBUG) { System.out.println("AssertStatement ::= assert Expression SEMICOLON"); } //$NON-NLS-1$ >- consumeSimpleAssertStatement() ; >- break; >- >- case 318 : if (DEBUG) { System.out.println("AssertStatement ::= assert Expression COLON Expression"); } //$NON-NLS-1$ >- consumeAssertStatement() ; >- break; >- >- case 319 : if (DEBUG) { System.out.println("BreakStatement ::= break SEMICOLON"); } //$NON-NLS-1$ >- consumeStatementBreak() ; >- break; >- >- case 320 : if (DEBUG) { System.out.println("BreakStatement ::= break Identifier SEMICOLON"); } //$NON-NLS-1$ >- consumeStatementBreakWithLabel() ; >- break; >- >- case 321 : if (DEBUG) { System.out.println("ContinueStatement ::= continue SEMICOLON"); } //$NON-NLS-1$ >- consumeStatementContinue() ; >- break; >- >- case 322 : if (DEBUG) { System.out.println("ContinueStatement ::= continue Identifier SEMICOLON"); } //$NON-NLS-1$ >- consumeStatementContinueWithLabel() ; >- break; >- >- case 323 : if (DEBUG) { System.out.println("ReturnStatement ::= return Expressionopt SEMICOLON"); } //$NON-NLS-1$ >- consumeStatementReturn() ; >- break; >- >- case 324 : if (DEBUG) { System.out.println("ThrowStatement ::= throw Expression SEMICOLON"); } //$NON-NLS-1$ >- consumeStatementThrow(); >- break; >- >- case 325 : if (DEBUG) { System.out.println("SynchronizedStatement ::= OnlySynchronized LPAREN..."); } //$NON-NLS-1$ >- consumeStatementSynchronized(); >- break; >- >- case 326 : if (DEBUG) { System.out.println("OnlySynchronized ::= synchronized"); } //$NON-NLS-1$ >- consumeOnlySynchronized(); >- break; >- >- case 327 : if (DEBUG) { System.out.println("TryStatement ::= try TryBlock Catches"); } //$NON-NLS-1$ >- consumeStatementTry(false, false); >- break; >- >- case 328 : if (DEBUG) { System.out.println("TryStatement ::= try TryBlock Catchesopt Finally"); } //$NON-NLS-1$ >- consumeStatementTry(true, false); >- break; >- >- case 329 : if (DEBUG) { System.out.println("TryStatementWithResources ::= try ResourceSpecification"); } //$NON-NLS-1$ >- consumeStatementTry(false, true); >- break; >- >- case 330 : if (DEBUG) { System.out.println("TryStatementWithResources ::= try ResourceSpecification"); } //$NON-NLS-1$ >- consumeStatementTry(true, true); >- break; >- >- case 331 : if (DEBUG) { System.out.println("ResourceSpecification ::= LPAREN Resources ;opt RPAREN"); } //$NON-NLS-1$ >- consumeResourceSpecification(); >- break; >- >- case 332 : if (DEBUG) { System.out.println(";opt ::="); } //$NON-NLS-1$ >- consumeResourceOptionalTrailingSemiColon(false); >- break; >- >- case 333 : if (DEBUG) { System.out.println(";opt ::= SEMICOLON"); } //$NON-NLS-1$ >- consumeResourceOptionalTrailingSemiColon(true); >- break; >- >- case 334 : if (DEBUG) { System.out.println("Resources ::= Resource"); } //$NON-NLS-1$ >- consumeSingleResource(); >- break; >- >- case 335 : if (DEBUG) { System.out.println("Resources ::= Resources TrailingSemiColon Resource"); } //$NON-NLS-1$ >- consumeMultipleResources(); >- break; >- >- case 336 : if (DEBUG) { System.out.println("TrailingSemiColon ::= SEMICOLON"); } //$NON-NLS-1$ >- consumeResourceOptionalTrailingSemiColon(true); >- break; >- >- case 337 : if (DEBUG) { System.out.println("Resource ::= Type PushModifiers VariableDeclaratorId..."); } //$NON-NLS-1$ >- consumeResourceAsLocalVariableDeclaration(); >- break; >- >- case 338 : if (DEBUG) { System.out.println("Resource ::= Modifiers Type PushRealModifiers..."); } //$NON-NLS-1$ >- consumeResourceAsLocalVariableDeclaration(); >- break; >- >- case 340 : if (DEBUG) { System.out.println("ExitTryBlock ::="); } //$NON-NLS-1$ >- consumeExitTryBlock(); >- break; >- >- case 342 : if (DEBUG) { System.out.println("Catches ::= Catches CatchClause"); } //$NON-NLS-1$ >- consumeCatches(); >- break; >- >- case 343 : if (DEBUG) { System.out.println("CatchClause ::= catch LPAREN CatchFormalParameter RPAREN"); } //$NON-NLS-1$ >- consumeStatementCatch() ; >- break; >- >- case 345 : if (DEBUG) { System.out.println("PushLPAREN ::= LPAREN"); } //$NON-NLS-1$ >- consumeLeftParen(); >- break; >- >- case 346 : if (DEBUG) { System.out.println("PushRPAREN ::= RPAREN"); } //$NON-NLS-1$ >- consumeRightParen(); >- break; >- >- case 351 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= this"); } //$NON-NLS-1$ >- consumePrimaryNoNewArrayThis(); >- break; >- >- case 352 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PushLPAREN Expression_NotName..."); } //$NON-NLS-1$ >- consumePrimaryNoNewArray(); >- break; >- >- case 353 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PushLPAREN Name PushRPAREN"); } //$NON-NLS-1$ >- consumePrimaryNoNewArrayWithName(); >- break; >- >- case 356 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT this"); } //$NON-NLS-1$ >- consumePrimaryNoNewArrayNameThis(); >- break; >- >- case 357 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT super"); } //$NON-NLS-1$ >- consumePrimaryNoNewArrayNameSuper(); >- break; >- >- case 358 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT class"); } //$NON-NLS-1$ >- consumePrimaryNoNewArrayName(); >- break; >- >- case 359 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name Dims DOT class"); } //$NON-NLS-1$ >- consumePrimaryNoNewArrayArrayType(); >- break; >- >- case 360 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PrimitiveType Dims DOT class"); } //$NON-NLS-1$ >- consumePrimaryNoNewArrayPrimitiveArrayType(); >- break; >- >- case 361 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PrimitiveType DOT class"); } //$NON-NLS-1$ >- consumePrimaryNoNewArrayPrimitiveType(); >- break; >- >- case 364 : if (DEBUG) { System.out.println("AllocationHeader ::= new ClassType LPAREN..."); } //$NON-NLS-1$ >- consumeAllocationHeader(); >- break; >- >- case 365 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= new..."); } //$NON-NLS-1$ >- consumeClassInstanceCreationExpressionWithTypeArguments(); >- break; >- >- case 366 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= new ClassType LPAREN"); } //$NON-NLS-1$ >- consumeClassInstanceCreationExpression(); >- break; >- >- case 367 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= Primary DOT new..."); } //$NON-NLS-1$ >- consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() ; >- break; >- >- case 368 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= Primary DOT new..."); } //$NON-NLS-1$ >- consumeClassInstanceCreationExpressionQualified() ; >- break; >- >- case 369 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::=..."); } //$NON-NLS-1$ >- consumeClassInstanceCreationExpressionQualified() ; >- break; >- >- case 370 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::=..."); } //$NON-NLS-1$ >- consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() ; >- break; >- >- case 371 : if (DEBUG) { System.out.println("ClassInstanceCreationExpressionName ::= Name DOT"); } //$NON-NLS-1$ >- consumeClassInstanceCreationExpressionName() ; >- break; >- >- case 372 : if (DEBUG) { System.out.println("UnqualifiedClassBodyopt ::="); } //$NON-NLS-1$ >- consumeClassBodyopt(); >- break; >- >- case 374 : if (DEBUG) { System.out.println("UnqualifiedEnterAnonymousClassBody ::="); } //$NON-NLS-1$ >- consumeEnterAnonymousClassBody(false); >- break; >- >- case 375 : if (DEBUG) { System.out.println("QualifiedClassBodyopt ::="); } //$NON-NLS-1$ >- consumeClassBodyopt(); >- break; >- >- case 377 : if (DEBUG) { System.out.println("QualifiedEnterAnonymousClassBody ::="); } //$NON-NLS-1$ >- consumeEnterAnonymousClassBody(true); >- break; >- >- case 379 : if (DEBUG) { System.out.println("ArgumentList ::= ArgumentList COMMA Expression"); } //$NON-NLS-1$ >- consumeArgumentList(); >- break; >- >- case 380 : if (DEBUG) { System.out.println("ArrayCreationHeader ::= new PrimitiveType..."); } //$NON-NLS-1$ >- consumeArrayCreationHeader(); >- break; >- >- case 381 : if (DEBUG) { System.out.println("ArrayCreationHeader ::= new ClassOrInterfaceType..."); } //$NON-NLS-1$ >- consumeArrayCreationHeader(); >- break; >- >- case 382 : if (DEBUG) { System.out.println("ArrayCreationWithoutArrayInitializer ::= new..."); } //$NON-NLS-1$ >- consumeArrayCreationExpressionWithoutInitializer(); >- break; >- >- case 383 : if (DEBUG) { System.out.println("ArrayCreationWithArrayInitializer ::= new PrimitiveType"); } //$NON-NLS-1$ >- consumeArrayCreationExpressionWithInitializer(); >- break; >- >- case 384 : if (DEBUG) { System.out.println("ArrayCreationWithoutArrayInitializer ::= new..."); } //$NON-NLS-1$ >- consumeArrayCreationExpressionWithoutInitializer(); >- break; >- >- case 385 : if (DEBUG) { System.out.println("ArrayCreationWithArrayInitializer ::= new..."); } //$NON-NLS-1$ >- consumeArrayCreationExpressionWithInitializer(); >- break; >- >- case 387 : if (DEBUG) { System.out.println("DimWithOrWithOutExprs ::= DimWithOrWithOutExprs..."); } //$NON-NLS-1$ >- consumeDimWithOrWithOutExprs(); >- break; >- >- case 389 : if (DEBUG) { System.out.println("DimWithOrWithOutExpr ::= LBRACKET RBRACKET"); } //$NON-NLS-1$ >- consumeDimWithOrWithOutExpr(); >- break; >- >- case 390 : if (DEBUG) { System.out.println("Dims ::= DimsLoop"); } //$NON-NLS-1$ >- consumeDims(); >- break; >- >- case 393 : if (DEBUG) { System.out.println("OneDimLoop ::= LBRACKET RBRACKET"); } //$NON-NLS-1$ >- consumeOneDimLoop(); >- break; >- >- case 394 : if (DEBUG) { System.out.println("FieldAccess ::= Primary DOT Identifier"); } //$NON-NLS-1$ >- consumeFieldAccess(false); >- break; >- >- case 395 : if (DEBUG) { System.out.println("FieldAccess ::= super DOT Identifier"); } //$NON-NLS-1$ >- consumeFieldAccess(true); >- break; >- >- case 396 : if (DEBUG) { System.out.println("MethodInvocation ::= Name LPAREN ArgumentListopt RPAREN"); } //$NON-NLS-1$ >- consumeMethodInvocationName(); >- break; >- >- case 397 : if (DEBUG) { System.out.println("MethodInvocation ::= Name DOT OnlyTypeArguments..."); } //$NON-NLS-1$ >- consumeMethodInvocationNameWithTypeArguments(); >- break; >- >- case 398 : if (DEBUG) { System.out.println("MethodInvocation ::= Primary DOT OnlyTypeArguments..."); } //$NON-NLS-1$ >- consumeMethodInvocationPrimaryWithTypeArguments(); >- break; >- >- case 399 : if (DEBUG) { System.out.println("MethodInvocation ::= Primary DOT Identifier LPAREN..."); } //$NON-NLS-1$ >- consumeMethodInvocationPrimary(); >- break; >- >- case 400 : if (DEBUG) { System.out.println("MethodInvocation ::= super DOT OnlyTypeArguments..."); } //$NON-NLS-1$ >- consumeMethodInvocationSuperWithTypeArguments(); >- break; >- >- case 401 : if (DEBUG) { System.out.println("MethodInvocation ::= super DOT Identifier LPAREN..."); } //$NON-NLS-1$ >- consumeMethodInvocationSuper(); >- break; >- >- case 402 : if (DEBUG) { System.out.println("ArrayAccess ::= Name LBRACKET Expression RBRACKET"); } //$NON-NLS-1$ >- consumeArrayAccess(true); >- break; >- >- case 403 : if (DEBUG) { System.out.println("ArrayAccess ::= PrimaryNoNewArray LBRACKET Expression..."); } //$NON-NLS-1$ >- consumeArrayAccess(false); >- break; >- >- case 404 : if (DEBUG) { System.out.println("ArrayAccess ::= ArrayCreationWithArrayInitializer..."); } //$NON-NLS-1$ >- consumeArrayAccess(false); >- break; >- >- case 406 : if (DEBUG) { System.out.println("PostfixExpression ::= Name"); } //$NON-NLS-1$ >- consumePostfixExpression(); >- break; >- >- case 409 : if (DEBUG) { System.out.println("PostIncrementExpression ::= PostfixExpression PLUS_PLUS"); } //$NON-NLS-1$ >- consumeUnaryExpression(OperatorIds.PLUS,true); >- break; >- >- case 410 : if (DEBUG) { System.out.println("PostDecrementExpression ::= PostfixExpression..."); } //$NON-NLS-1$ >- consumeUnaryExpression(OperatorIds.MINUS,true); >- break; >- >- case 411 : if (DEBUG) { System.out.println("PushPosition ::="); } //$NON-NLS-1$ >- consumePushPosition(); >- break; >- >- case 414 : if (DEBUG) { System.out.println("UnaryExpression ::= PLUS PushPosition UnaryExpression"); } //$NON-NLS-1$ >- consumeUnaryExpression(OperatorIds.PLUS); >- break; >- >- case 415 : if (DEBUG) { System.out.println("UnaryExpression ::= MINUS PushPosition UnaryExpression"); } //$NON-NLS-1$ >- consumeUnaryExpression(OperatorIds.MINUS); >- break; >- >- case 417 : if (DEBUG) { System.out.println("PreIncrementExpression ::= PLUS_PLUS PushPosition..."); } //$NON-NLS-1$ >- consumeUnaryExpression(OperatorIds.PLUS,false); >- break; >- >- case 418 : if (DEBUG) { System.out.println("PreDecrementExpression ::= MINUS_MINUS PushPosition..."); } //$NON-NLS-1$ >- consumeUnaryExpression(OperatorIds.MINUS,false); >- break; >- >- case 420 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus ::= TWIDDLE PushPosition..."); } //$NON-NLS-1$ >- consumeUnaryExpression(OperatorIds.TWIDDLE); >- break; >- >- case 421 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus ::= NOT PushPosition..."); } //$NON-NLS-1$ >- consumeUnaryExpression(OperatorIds.NOT); >- break; >- >- case 423 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN PrimitiveType Dimsopt..."); } //$NON-NLS-1$ >- consumeCastExpressionWithPrimitiveType(); >- break; >- >- case 424 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name..."); } //$NON-NLS-1$ >- consumeCastExpressionWithGenericsArray(); >- break; >- >- case 425 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name..."); } //$NON-NLS-1$ >- consumeCastExpressionWithQualifiedGenericsArray(); >- break; >- >- case 426 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name PushRPAREN..."); } //$NON-NLS-1$ >- consumeCastExpressionLL1(); >- break; >- >- case 427 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name Dims PushRPAREN..."); } //$NON-NLS-1$ >- consumeCastExpressionWithNameArray(); >- break; >- >- case 428 : if (DEBUG) { System.out.println("OnlyTypeArgumentsForCastExpression ::= OnlyTypeArguments"); } //$NON-NLS-1$ >- consumeOnlyTypeArgumentsForCastExpression(); >- break; >- >- case 429 : if (DEBUG) { System.out.println("InsideCastExpression ::="); } //$NON-NLS-1$ >- consumeInsideCastExpression(); >- break; >- >- case 430 : if (DEBUG) { System.out.println("InsideCastExpressionLL1 ::="); } //$NON-NLS-1$ >- consumeInsideCastExpressionLL1(); >- break; >- >- case 431 : if (DEBUG) { System.out.println("InsideCastExpressionWithQualifiedGenerics ::="); } //$NON-NLS-1$ >- consumeInsideCastExpressionWithQualifiedGenerics(); >- break; >- >- case 433 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.MULTIPLY); >- break; >- >- case 434 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.DIVIDE); >- break; >- >- case 435 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.REMAINDER); >- break; >- >- case 437 : if (DEBUG) { System.out.println("AdditiveExpression ::= AdditiveExpression PLUS..."); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.PLUS); >- break; >- >- case 438 : if (DEBUG) { System.out.println("AdditiveExpression ::= AdditiveExpression MINUS..."); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.MINUS); >- break; >- >- case 440 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression LEFT_SHIFT..."); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.LEFT_SHIFT); >- break; >- >- case 441 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression RIGHT_SHIFT..."); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.RIGHT_SHIFT); >- break; >- >- case 442 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression UNSIGNED_RIGHT_SHIFT"); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.UNSIGNED_RIGHT_SHIFT); >- break; >- >- case 444 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS..."); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.LESS); >- break; >- >- case 445 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression GREATER..."); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.GREATER); >- break; >- >- case 446 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS_EQUAL"); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.LESS_EQUAL); >- break; >- >- case 447 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression..."); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.GREATER_EQUAL); >- break; >- >- case 449 : if (DEBUG) { System.out.println("InstanceofExpression ::= InstanceofExpression instanceof"); } //$NON-NLS-1$ >- consumeInstanceOfExpression(); >- break; >- >- case 451 : if (DEBUG) { System.out.println("EqualityExpression ::= EqualityExpression EQUAL_EQUAL..."); } //$NON-NLS-1$ >- consumeEqualityExpression(OperatorIds.EQUAL_EQUAL); >- break; >- >- case 452 : if (DEBUG) { System.out.println("EqualityExpression ::= EqualityExpression NOT_EQUAL..."); } //$NON-NLS-1$ >- consumeEqualityExpression(OperatorIds.NOT_EQUAL); >- break; >- >- case 454 : if (DEBUG) { System.out.println("AndExpression ::= AndExpression AND EqualityExpression"); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.AND); >- break; >- >- case 456 : if (DEBUG) { System.out.println("ExclusiveOrExpression ::= ExclusiveOrExpression XOR..."); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.XOR); >- break; >- >- case 458 : if (DEBUG) { System.out.println("InclusiveOrExpression ::= InclusiveOrExpression OR..."); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.OR); >- break; >- >- case 460 : if (DEBUG) { System.out.println("ConditionalAndExpression ::= ConditionalAndExpression..."); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.AND_AND); >- break; >- >- case 462 : if (DEBUG) { System.out.println("ConditionalOrExpression ::= ConditionalOrExpression..."); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.OR_OR); >- break; >- >- case 464 : if (DEBUG) { System.out.println("ConditionalExpression ::= ConditionalOrExpression..."); } //$NON-NLS-1$ >- consumeConditionalExpression(OperatorIds.QUESTIONCOLON) ; >- break; >- >- case 467 : if (DEBUG) { System.out.println("Assignment ::= PostfixExpression AssignmentOperator..."); } //$NON-NLS-1$ >- consumeAssignment(); >- break; >- >- case 469 : if (DEBUG) { System.out.println("Assignment ::= InvalidArrayInitializerAssignement"); } //$NON-NLS-1$ >- ignoreExpressionAssignment(); >- break; >- >- case 470 : if (DEBUG) { System.out.println("AssignmentOperator ::= EQUAL"); } //$NON-NLS-1$ >- consumeAssignmentOperator(EQUAL); >- break; >- >- case 471 : if (DEBUG) { System.out.println("AssignmentOperator ::= MULTIPLY_EQUAL"); } //$NON-NLS-1$ >- consumeAssignmentOperator(MULTIPLY); >- break; >- >- case 472 : if (DEBUG) { System.out.println("AssignmentOperator ::= DIVIDE_EQUAL"); } //$NON-NLS-1$ >- consumeAssignmentOperator(DIVIDE); >- break; >- >- case 473 : if (DEBUG) { System.out.println("AssignmentOperator ::= REMAINDER_EQUAL"); } //$NON-NLS-1$ >- consumeAssignmentOperator(REMAINDER); >- break; >- >- case 474 : if (DEBUG) { System.out.println("AssignmentOperator ::= PLUS_EQUAL"); } //$NON-NLS-1$ >- consumeAssignmentOperator(PLUS); >- break; >- >- case 475 : if (DEBUG) { System.out.println("AssignmentOperator ::= MINUS_EQUAL"); } //$NON-NLS-1$ >- consumeAssignmentOperator(MINUS); >- break; >- >- case 476 : if (DEBUG) { System.out.println("AssignmentOperator ::= LEFT_SHIFT_EQUAL"); } //$NON-NLS-1$ >- consumeAssignmentOperator(LEFT_SHIFT); >- break; >- >- case 477 : if (DEBUG) { System.out.println("AssignmentOperator ::= RIGHT_SHIFT_EQUAL"); } //$NON-NLS-1$ >- consumeAssignmentOperator(RIGHT_SHIFT); >- break; >- >- case 478 : if (DEBUG) { System.out.println("AssignmentOperator ::= UNSIGNED_RIGHT_SHIFT_EQUAL"); } //$NON-NLS-1$ >- consumeAssignmentOperator(UNSIGNED_RIGHT_SHIFT); >- break; >- >- case 479 : if (DEBUG) { System.out.println("AssignmentOperator ::= AND_EQUAL"); } //$NON-NLS-1$ >- consumeAssignmentOperator(AND); >- break; >- >- case 480 : if (DEBUG) { System.out.println("AssignmentOperator ::= XOR_EQUAL"); } //$NON-NLS-1$ >- consumeAssignmentOperator(XOR); >- break; >- >- case 481 : if (DEBUG) { System.out.println("AssignmentOperator ::= OR_EQUAL"); } //$NON-NLS-1$ >- consumeAssignmentOperator(OR); >- break; >- >- case 485 : if (DEBUG) { System.out.println("Expressionopt ::="); } //$NON-NLS-1$ >- consumeEmptyExpression(); >- break; >- >- case 490 : if (DEBUG) { System.out.println("ClassBodyDeclarationsopt ::="); } //$NON-NLS-1$ >- consumeEmptyClassBodyDeclarationsopt(); >- break; >- >- case 491 : if (DEBUG) { System.out.println("ClassBodyDeclarationsopt ::= NestedType..."); } //$NON-NLS-1$ >- consumeClassBodyDeclarationsopt(); >- break; >- >- case 492 : if (DEBUG) { System.out.println("Modifiersopt ::="); } //$NON-NLS-1$ >- consumeDefaultModifiers(); >- break; >- >- case 493 : if (DEBUG) { System.out.println("Modifiersopt ::= Modifiers"); } //$NON-NLS-1$ >- consumeModifiers(); >- break; >- >- case 494 : if (DEBUG) { System.out.println("BlockStatementsopt ::="); } //$NON-NLS-1$ >- consumeEmptyBlockStatementsopt(); >- break; >- >- case 496 : if (DEBUG) { System.out.println("Dimsopt ::="); } //$NON-NLS-1$ >- consumeEmptyDimsopt(); >- break; >- >- case 498 : if (DEBUG) { System.out.println("ArgumentListopt ::="); } //$NON-NLS-1$ >- consumeEmptyArgumentListopt(); >- break; >- >- case 502 : if (DEBUG) { System.out.println("FormalParameterListopt ::="); } //$NON-NLS-1$ >- consumeFormalParameterListopt(); >- break; >- >- case 506 : if (DEBUG) { System.out.println("InterfaceMemberDeclarationsopt ::="); } //$NON-NLS-1$ >- consumeEmptyInterfaceMemberDeclarationsopt(); >- break; >- >- case 507 : if (DEBUG) { System.out.println("InterfaceMemberDeclarationsopt ::= NestedType..."); } //$NON-NLS-1$ >- consumeInterfaceMemberDeclarationsopt(); >- break; >- >- case 508 : if (DEBUG) { System.out.println("NestedType ::="); } //$NON-NLS-1$ >- consumeNestedType(); >- break; >- >- case 509 : if (DEBUG) { System.out.println("ForInitopt ::="); } //$NON-NLS-1$ >- consumeEmptyForInitopt(); >- break; >- >- case 511 : if (DEBUG) { System.out.println("ForUpdateopt ::="); } //$NON-NLS-1$ >- consumeEmptyForUpdateopt(); >- break; >- >- case 515 : if (DEBUG) { System.out.println("Catchesopt ::="); } //$NON-NLS-1$ >- consumeEmptyCatchesopt(); >- break; >- >- case 517 : if (DEBUG) { System.out.println("EnumDeclaration ::= EnumHeader EnumBody"); } //$NON-NLS-1$ >- consumeEnumDeclaration(); >- break; >- >- case 518 : if (DEBUG) { System.out.println("EnumHeader ::= EnumHeaderName ClassHeaderImplementsopt"); } //$NON-NLS-1$ >- consumeEnumHeader(); >- break; >- >- case 519 : if (DEBUG) { System.out.println("EnumHeaderName ::= Modifiersopt enum Identifier"); } //$NON-NLS-1$ >- consumeEnumHeaderName(); >- break; >- >- case 520 : if (DEBUG) { System.out.println("EnumHeaderName ::= Modifiersopt enum Identifier..."); } //$NON-NLS-1$ >- consumeEnumHeaderNameWithTypeParameters(); >- break; >- >- case 521 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumBodyDeclarationsopt RBRACE"); } //$NON-NLS-1$ >- consumeEnumBodyNoConstants(); >- break; >- >- case 522 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE COMMA EnumBodyDeclarationsopt..."); } //$NON-NLS-1$ >- consumeEnumBodyNoConstants(); >- break; >- >- case 523 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumConstants COMMA..."); } //$NON-NLS-1$ >- consumeEnumBodyWithConstants(); >- break; >- >- case 524 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumConstants..."); } //$NON-NLS-1$ >- consumeEnumBodyWithConstants(); >- break; >- >- case 526 : if (DEBUG) { System.out.println("EnumConstants ::= EnumConstants COMMA EnumConstant"); } //$NON-NLS-1$ >- consumeEnumConstants(); >- break; >- >- case 527 : if (DEBUG) { System.out.println("EnumConstantHeaderName ::= Modifiersopt Identifier"); } //$NON-NLS-1$ >- consumeEnumConstantHeaderName(); >- break; >- >- case 528 : if (DEBUG) { System.out.println("EnumConstantHeader ::= EnumConstantHeaderName..."); } //$NON-NLS-1$ >- consumeEnumConstantHeader(); >- break; >- >- case 529 : if (DEBUG) { System.out.println("EnumConstant ::= EnumConstantHeader ForceNoDiet..."); } //$NON-NLS-1$ >- consumeEnumConstantWithClassBody(); >- break; >- >- case 530 : if (DEBUG) { System.out.println("EnumConstant ::= EnumConstantHeader"); } //$NON-NLS-1$ >- consumeEnumConstantNoClassBody(); >- break; >- >- case 531 : if (DEBUG) { System.out.println("Arguments ::= LPAREN ArgumentListopt RPAREN"); } //$NON-NLS-1$ >- consumeArguments(); >- break; >- >- case 532 : if (DEBUG) { System.out.println("Argumentsopt ::="); } //$NON-NLS-1$ >- consumeEmptyArguments(); >- break; >- >- case 534 : if (DEBUG) { System.out.println("EnumDeclarations ::= SEMICOLON ClassBodyDeclarationsopt"); } //$NON-NLS-1$ >- consumeEnumDeclarations(); >- break; >- >- case 535 : if (DEBUG) { System.out.println("EnumBodyDeclarationsopt ::="); } //$NON-NLS-1$ >- consumeEmptyEnumDeclarations(); >- break; >- >- case 537 : if (DEBUG) { System.out.println("EnhancedForStatement ::= EnhancedForStatementHeader..."); } //$NON-NLS-1$ >- consumeEnhancedForStatement(); >- break; >- >- case 538 : if (DEBUG) { System.out.println("EnhancedForStatementNoShortIf ::=..."); } //$NON-NLS-1$ >- consumeEnhancedForStatement(); >- break; >- >- case 539 : if (DEBUG) { System.out.println("EnhancedForStatementHeaderInit ::= for LPAREN Type..."); } //$NON-NLS-1$ >- consumeEnhancedForStatementHeaderInit(false); >- break; >- >- case 540 : if (DEBUG) { System.out.println("EnhancedForStatementHeaderInit ::= for LPAREN Modifiers"); } //$NON-NLS-1$ >- consumeEnhancedForStatementHeaderInit(true); >- break; >- >- case 541 : if (DEBUG) { System.out.println("EnhancedForStatementHeader ::=..."); } //$NON-NLS-1$ >- consumeEnhancedForStatementHeader(); >- break; >- >- case 542 : if (DEBUG) { System.out.println("SingleStaticImportDeclaration ::=..."); } //$NON-NLS-1$ >- consumeImportDeclaration(); >- break; >- >- case 543 : if (DEBUG) { System.out.println("SingleStaticImportDeclarationName ::= import static Name"); } //$NON-NLS-1$ >- consumeSingleStaticImportDeclarationName(); >- break; >- >- case 544 : if (DEBUG) { System.out.println("StaticImportOnDemandDeclaration ::=..."); } //$NON-NLS-1$ >- consumeImportDeclaration(); >- break; >- >- case 545 : if (DEBUG) { System.out.println("StaticImportOnDemandDeclarationName ::= import static..."); } //$NON-NLS-1$ >- consumeStaticImportOnDemandDeclarationName(); >- break; >- >- case 546 : if (DEBUG) { System.out.println("TypeArguments ::= LESS TypeArgumentList1"); } //$NON-NLS-1$ >- consumeTypeArguments(); >- break; >- >- case 547 : if (DEBUG) { System.out.println("OnlyTypeArguments ::= LESS TypeArgumentList1"); } //$NON-NLS-1$ >- consumeOnlyTypeArguments(); >- break; >- >- case 549 : if (DEBUG) { System.out.println("TypeArgumentList1 ::= TypeArgumentList COMMA..."); } //$NON-NLS-1$ >- consumeTypeArgumentList1(); >- break; >- >- case 551 : if (DEBUG) { System.out.println("TypeArgumentList ::= TypeArgumentList COMMA TypeArgument"); } //$NON-NLS-1$ >- consumeTypeArgumentList(); >- break; >- >- case 552 : if (DEBUG) { System.out.println("TypeArgument ::= ReferenceType"); } //$NON-NLS-1$ >- consumeTypeArgument(); >- break; >- >- case 556 : if (DEBUG) { System.out.println("ReferenceType1 ::= ReferenceType GREATER"); } //$NON-NLS-1$ >- consumeReferenceType1(); >- break; >- >- case 557 : if (DEBUG) { System.out.println("ReferenceType1 ::= ClassOrInterface LESS..."); } //$NON-NLS-1$ >- consumeTypeArgumentReferenceType1(); >- break; >- >- case 559 : if (DEBUG) { System.out.println("TypeArgumentList2 ::= TypeArgumentList COMMA..."); } //$NON-NLS-1$ >- consumeTypeArgumentList2(); >- break; >- >- case 562 : if (DEBUG) { System.out.println("ReferenceType2 ::= ReferenceType RIGHT_SHIFT"); } //$NON-NLS-1$ >- consumeReferenceType2(); >- break; >- >- case 563 : if (DEBUG) { System.out.println("ReferenceType2 ::= ClassOrInterface LESS..."); } //$NON-NLS-1$ >- consumeTypeArgumentReferenceType2(); >- break; >- >- case 565 : if (DEBUG) { System.out.println("TypeArgumentList3 ::= TypeArgumentList COMMA..."); } //$NON-NLS-1$ >- consumeTypeArgumentList3(); >- break; >- >- case 568 : if (DEBUG) { System.out.println("ReferenceType3 ::= ReferenceType UNSIGNED_RIGHT_SHIFT"); } //$NON-NLS-1$ >- consumeReferenceType3(); >- break; >- >- case 569 : if (DEBUG) { System.out.println("Wildcard ::= QUESTION"); } //$NON-NLS-1$ >- consumeWildcard(); >- break; >- >- case 570 : if (DEBUG) { System.out.println("Wildcard ::= QUESTION WildcardBounds"); } //$NON-NLS-1$ >- consumeWildcardWithBounds(); >- break; >- >- case 571 : if (DEBUG) { System.out.println("WildcardBounds ::= extends ReferenceType"); } //$NON-NLS-1$ >- consumeWildcardBoundsExtends(); >- break; >- >- case 572 : if (DEBUG) { System.out.println("WildcardBounds ::= super ReferenceType"); } //$NON-NLS-1$ >- consumeWildcardBoundsSuper(); >- break; >- >- case 573 : if (DEBUG) { System.out.println("Wildcard1 ::= QUESTION GREATER"); } //$NON-NLS-1$ >- consumeWildcard1(); >- break; >- >- case 574 : if (DEBUG) { System.out.println("Wildcard1 ::= QUESTION WildcardBounds1"); } //$NON-NLS-1$ >- consumeWildcard1WithBounds(); >- break; >- >- case 575 : if (DEBUG) { System.out.println("WildcardBounds1 ::= extends ReferenceType1"); } //$NON-NLS-1$ >- consumeWildcardBounds1Extends(); >- break; >- >- case 576 : if (DEBUG) { System.out.println("WildcardBounds1 ::= super ReferenceType1"); } //$NON-NLS-1$ >- consumeWildcardBounds1Super(); >- break; >- >- case 577 : if (DEBUG) { System.out.println("Wildcard2 ::= QUESTION RIGHT_SHIFT"); } //$NON-NLS-1$ >- consumeWildcard2(); >- break; >- >- case 578 : if (DEBUG) { System.out.println("Wildcard2 ::= QUESTION WildcardBounds2"); } //$NON-NLS-1$ >- consumeWildcard2WithBounds(); >- break; >- >- case 579 : if (DEBUG) { System.out.println("WildcardBounds2 ::= extends ReferenceType2"); } //$NON-NLS-1$ >- consumeWildcardBounds2Extends(); >- break; >- >- case 580 : if (DEBUG) { System.out.println("WildcardBounds2 ::= super ReferenceType2"); } //$NON-NLS-1$ >- consumeWildcardBounds2Super(); >- break; >- >- case 581 : if (DEBUG) { System.out.println("Wildcard3 ::= QUESTION UNSIGNED_RIGHT_SHIFT"); } //$NON-NLS-1$ >- consumeWildcard3(); >- break; >- >- case 582 : if (DEBUG) { System.out.println("Wildcard3 ::= QUESTION WildcardBounds3"); } //$NON-NLS-1$ >- consumeWildcard3WithBounds(); >- break; >- >- case 583 : if (DEBUG) { System.out.println("WildcardBounds3 ::= extends ReferenceType3"); } //$NON-NLS-1$ >- consumeWildcardBounds3Extends(); >- break; >- >- case 584 : if (DEBUG) { System.out.println("WildcardBounds3 ::= super ReferenceType3"); } //$NON-NLS-1$ >- consumeWildcardBounds3Super(); >- break; >- >- case 585 : if (DEBUG) { System.out.println("TypeParameterHeader ::= Identifier"); } //$NON-NLS-1$ >- consumeTypeParameterHeader(); >- break; >- >- case 586 : if (DEBUG) { System.out.println("TypeParameters ::= LESS TypeParameterList1"); } //$NON-NLS-1$ >- consumeTypeParameters(); >- break; >- >- case 588 : if (DEBUG) { System.out.println("TypeParameterList ::= TypeParameterList COMMA..."); } //$NON-NLS-1$ >- consumeTypeParameterList(); >- break; >- >- case 590 : if (DEBUG) { System.out.println("TypeParameter ::= TypeParameterHeader extends..."); } //$NON-NLS-1$ >- consumeTypeParameterWithExtends(); >- break; >- >- case 591 : if (DEBUG) { System.out.println("TypeParameter ::= TypeParameterHeader extends..."); } //$NON-NLS-1$ >- consumeTypeParameterWithExtendsAndBounds(); >- break; >- >- case 593 : if (DEBUG) { System.out.println("AdditionalBoundList ::= AdditionalBoundList..."); } //$NON-NLS-1$ >- consumeAdditionalBoundList(); >- break; >- >- case 594 : if (DEBUG) { System.out.println("AdditionalBound ::= AND ReferenceType"); } //$NON-NLS-1$ >- consumeAdditionalBound(); >- break; >- >- case 596 : if (DEBUG) { System.out.println("TypeParameterList1 ::= TypeParameterList COMMA..."); } //$NON-NLS-1$ >- consumeTypeParameterList1(); >- break; >- >- case 597 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader GREATER"); } //$NON-NLS-1$ >- consumeTypeParameter1(); >- break; >- >- case 598 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader extends..."); } //$NON-NLS-1$ >- consumeTypeParameter1WithExtends(); >- break; >- >- case 599 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader extends..."); } //$NON-NLS-1$ >- consumeTypeParameter1WithExtendsAndBounds(); >- break; >- >- case 601 : if (DEBUG) { System.out.println("AdditionalBoundList1 ::= AdditionalBoundList..."); } //$NON-NLS-1$ >- consumeAdditionalBoundList1(); >- break; >- >- case 602 : if (DEBUG) { System.out.println("AdditionalBound1 ::= AND ReferenceType1"); } //$NON-NLS-1$ >- consumeAdditionalBound1(); >- break; >- >- case 608 : if (DEBUG) { System.out.println("UnaryExpression_NotName ::= PLUS PushPosition..."); } //$NON-NLS-1$ >- consumeUnaryExpression(OperatorIds.PLUS); >- break; >- >- case 609 : if (DEBUG) { System.out.println("UnaryExpression_NotName ::= MINUS PushPosition..."); } //$NON-NLS-1$ >- consumeUnaryExpression(OperatorIds.MINUS); >- break; >- >- case 612 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus_NotName ::= TWIDDLE..."); } //$NON-NLS-1$ >- consumeUnaryExpression(OperatorIds.TWIDDLE); >- break; >- >- case 613 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus_NotName ::= NOT PushPosition"); } //$NON-NLS-1$ >- consumeUnaryExpression(OperatorIds.NOT); >- break; >- >- case 616 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.MULTIPLY); >- break; >- >- case 617 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name MULTIPLY..."); } //$NON-NLS-1$ >- consumeBinaryExpressionWithName(OperatorIds.MULTIPLY); >- break; >- >- case 618 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.DIVIDE); >- break; >- >- case 619 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name DIVIDE..."); } //$NON-NLS-1$ >- consumeBinaryExpressionWithName(OperatorIds.DIVIDE); >- break; >- >- case 620 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.REMAINDER); >- break; >- >- case 621 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name REMAINDER..."); } //$NON-NLS-1$ >- consumeBinaryExpressionWithName(OperatorIds.REMAINDER); >- break; >- >- case 623 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::=..."); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.PLUS); >- break; >- >- case 624 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::= Name PLUS..."); } //$NON-NLS-1$ >- consumeBinaryExpressionWithName(OperatorIds.PLUS); >- break; >- >- case 625 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::=..."); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.MINUS); >- break; >- >- case 626 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::= Name MINUS..."); } //$NON-NLS-1$ >- consumeBinaryExpressionWithName(OperatorIds.MINUS); >- break; >- >- case 628 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.LEFT_SHIFT); >- break; >- >- case 629 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name LEFT_SHIFT..."); } //$NON-NLS-1$ >- consumeBinaryExpressionWithName(OperatorIds.LEFT_SHIFT); >- break; >- >- case 630 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.RIGHT_SHIFT); >- break; >- >- case 631 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name RIGHT_SHIFT..."); } //$NON-NLS-1$ >- consumeBinaryExpressionWithName(OperatorIds.RIGHT_SHIFT); >- break; >- >- case 632 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.UNSIGNED_RIGHT_SHIFT); >- break; >- >- case 633 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name UNSIGNED_RIGHT_SHIFT..."); } //$NON-NLS-1$ >- consumeBinaryExpressionWithName(OperatorIds.UNSIGNED_RIGHT_SHIFT); >- break; >- >- case 635 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= ShiftExpression_NotName"); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.LESS); >- break; >- >- case 636 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name LESS..."); } //$NON-NLS-1$ >- consumeBinaryExpressionWithName(OperatorIds.LESS); >- break; >- >- case 637 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= ShiftExpression_NotName"); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.GREATER); >- break; >- >- case 638 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name GREATER..."); } //$NON-NLS-1$ >- consumeBinaryExpressionWithName(OperatorIds.GREATER); >- break; >- >- case 639 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::=..."); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.LESS_EQUAL); >- break; >- >- case 640 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name LESS_EQUAL..."); } //$NON-NLS-1$ >- consumeBinaryExpressionWithName(OperatorIds.LESS_EQUAL); >- break; >- >- case 641 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::=..."); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.GREATER_EQUAL); >- break; >- >- case 642 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name GREATER_EQUAL..."); } //$NON-NLS-1$ >- consumeBinaryExpressionWithName(OperatorIds.GREATER_EQUAL); >- break; >- >- case 644 : if (DEBUG) { System.out.println("InstanceofExpression_NotName ::= Name instanceof..."); } //$NON-NLS-1$ >- consumeInstanceOfExpressionWithName(); >- break; >- >- case 645 : if (DEBUG) { System.out.println("InstanceofExpression_NotName ::=..."); } //$NON-NLS-1$ >- consumeInstanceOfExpression(); >- break; >- >- case 647 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::=..."); } //$NON-NLS-1$ >- consumeEqualityExpression(OperatorIds.EQUAL_EQUAL); >- break; >- >- case 648 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::= Name EQUAL_EQUAL..."); } //$NON-NLS-1$ >- consumeEqualityExpressionWithName(OperatorIds.EQUAL_EQUAL); >- break; >- >- case 649 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::=..."); } //$NON-NLS-1$ >- consumeEqualityExpression(OperatorIds.NOT_EQUAL); >- break; >- >- case 650 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::= Name NOT_EQUAL..."); } //$NON-NLS-1$ >- consumeEqualityExpressionWithName(OperatorIds.NOT_EQUAL); >- break; >- >- case 652 : if (DEBUG) { System.out.println("AndExpression_NotName ::= AndExpression_NotName AND..."); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.AND); >- break; >- >- case 653 : if (DEBUG) { System.out.println("AndExpression_NotName ::= Name AND EqualityExpression"); } //$NON-NLS-1$ >- consumeBinaryExpressionWithName(OperatorIds.AND); >- break; >- >- case 655 : if (DEBUG) { System.out.println("ExclusiveOrExpression_NotName ::=..."); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.XOR); >- break; >- >- case 656 : if (DEBUG) { System.out.println("ExclusiveOrExpression_NotName ::= Name XOR AndExpression"); } //$NON-NLS-1$ >- consumeBinaryExpressionWithName(OperatorIds.XOR); >- break; >- >- case 658 : if (DEBUG) { System.out.println("InclusiveOrExpression_NotName ::=..."); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.OR); >- break; >- >- case 659 : if (DEBUG) { System.out.println("InclusiveOrExpression_NotName ::= Name OR..."); } //$NON-NLS-1$ >- consumeBinaryExpressionWithName(OperatorIds.OR); >- break; >- >- case 661 : if (DEBUG) { System.out.println("ConditionalAndExpression_NotName ::=..."); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.AND_AND); >- break; >- >- case 662 : if (DEBUG) { System.out.println("ConditionalAndExpression_NotName ::= Name AND_AND..."); } //$NON-NLS-1$ >- consumeBinaryExpressionWithName(OperatorIds.AND_AND); >- break; >- >- case 664 : if (DEBUG) { System.out.println("ConditionalOrExpression_NotName ::=..."); } //$NON-NLS-1$ >- consumeBinaryExpression(OperatorIds.OR_OR); >- break; >- >- case 665 : if (DEBUG) { System.out.println("ConditionalOrExpression_NotName ::= Name OR_OR..."); } //$NON-NLS-1$ >- consumeBinaryExpressionWithName(OperatorIds.OR_OR); >- break; >- >- case 667 : if (DEBUG) { System.out.println("ConditionalExpression_NotName ::=..."); } //$NON-NLS-1$ >- consumeConditionalExpression(OperatorIds.QUESTIONCOLON) ; >- break; >- >- case 668 : if (DEBUG) { System.out.println("ConditionalExpression_NotName ::= Name QUESTION..."); } //$NON-NLS-1$ >- consumeConditionalExpressionWithName(OperatorIds.QUESTIONCOLON) ; >- break; >- >- case 672 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= Modifiers AT..."); } //$NON-NLS-1$ >- consumeAnnotationTypeDeclarationHeaderName() ; >- break; >- >- case 673 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= Modifiers AT..."); } //$NON-NLS-1$ >- consumeAnnotationTypeDeclarationHeaderNameWithTypeParameters() ; >- break; >- >- case 674 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= AT..."); } //$NON-NLS-1$ >- consumeAnnotationTypeDeclarationHeaderNameWithTypeParameters() ; >- break; >- >- case 675 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= AT..."); } //$NON-NLS-1$ >- consumeAnnotationTypeDeclarationHeaderName() ; >- break; >- >- case 676 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeader ::=..."); } //$NON-NLS-1$ >- consumeAnnotationTypeDeclarationHeader() ; >- break; >- >- case 677 : if (DEBUG) { System.out.println("AnnotationTypeDeclaration ::=..."); } //$NON-NLS-1$ >- consumeAnnotationTypeDeclaration() ; >- break; >- >- case 679 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarationsopt ::="); } //$NON-NLS-1$ >- consumeEmptyAnnotationTypeMemberDeclarationsopt() ; >- break; >- >- case 680 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarationsopt ::= NestedType..."); } //$NON-NLS-1$ >- consumeAnnotationTypeMemberDeclarationsopt() ; >- break; >- >- case 682 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarations ::=..."); } //$NON-NLS-1$ >- consumeAnnotationTypeMemberDeclarations() ; >- break; >- >- case 683 : if (DEBUG) { System.out.println("AnnotationMethodHeaderName ::= Modifiersopt..."); } //$NON-NLS-1$ >- consumeMethodHeaderNameWithTypeParameters(true); >- break; >- >- case 684 : if (DEBUG) { System.out.println("AnnotationMethodHeaderName ::= Modifiersopt Type..."); } //$NON-NLS-1$ >- consumeMethodHeaderName(true); >- break; >- >- case 685 : if (DEBUG) { System.out.println("AnnotationMethodHeaderDefaultValueopt ::="); } //$NON-NLS-1$ >- consumeEmptyMethodHeaderDefaultValue() ; >- break; >- >- case 686 : if (DEBUG) { System.out.println("AnnotationMethodHeaderDefaultValueopt ::= DefaultValue"); } //$NON-NLS-1$ >- consumeMethodHeaderDefaultValue(); >- break; >- >- case 687 : if (DEBUG) { System.out.println("AnnotationMethodHeader ::= AnnotationMethodHeaderName..."); } //$NON-NLS-1$ >- consumeMethodHeader(); >- break; >- >- case 688 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclaration ::=..."); } //$NON-NLS-1$ >- consumeAnnotationTypeMemberDeclaration() ; >- break; >- >- case 696 : if (DEBUG) { System.out.println("AnnotationName ::= AT Name"); } //$NON-NLS-1$ >- consumeAnnotationName() ; >- break; >- >- case 697 : if (DEBUG) { System.out.println("NormalAnnotation ::= AnnotationName LPAREN..."); } //$NON-NLS-1$ >- consumeNormalAnnotation() ; >- break; >- >- case 698 : if (DEBUG) { System.out.println("MemberValuePairsopt ::="); } //$NON-NLS-1$ >- consumeEmptyMemberValuePairsopt() ; >- break; >- >- case 701 : if (DEBUG) { System.out.println("MemberValuePairs ::= MemberValuePairs COMMA..."); } //$NON-NLS-1$ >- consumeMemberValuePairs() ; >- break; >- >- case 702 : if (DEBUG) { System.out.println("MemberValuePair ::= SimpleName EQUAL EnterMemberValue..."); } //$NON-NLS-1$ >- consumeMemberValuePair() ; >- break; >- >- case 703 : if (DEBUG) { System.out.println("EnterMemberValue ::="); } //$NON-NLS-1$ >- consumeEnterMemberValue() ; >- break; >- >- case 704 : if (DEBUG) { System.out.println("ExitMemberValue ::="); } //$NON-NLS-1$ >- consumeExitMemberValue() ; >- break; >- >- case 706 : if (DEBUG) { System.out.println("MemberValue ::= Name"); } //$NON-NLS-1$ >- consumeMemberValueAsName() ; >- break; >- >- case 709 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); } //$NON-NLS-1$ >- consumeMemberValueArrayInitializer() ; >- break; >- >- case 710 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); } //$NON-NLS-1$ >- consumeMemberValueArrayInitializer() ; >- break; >- >- case 711 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); } //$NON-NLS-1$ >- consumeEmptyMemberValueArrayInitializer() ; >- break; >- >- case 712 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); } //$NON-NLS-1$ >- consumeEmptyMemberValueArrayInitializer() ; >- break; >- >- case 713 : if (DEBUG) { System.out.println("EnterMemberValueArrayInitializer ::="); } //$NON-NLS-1$ >- consumeEnterMemberValueArrayInitializer() ; >- break; >- >- case 715 : if (DEBUG) { System.out.println("MemberValues ::= MemberValues COMMA MemberValue"); } //$NON-NLS-1$ >- consumeMemberValues() ; >- break; >- >- case 716 : if (DEBUG) { System.out.println("MarkerAnnotation ::= AnnotationName"); } //$NON-NLS-1$ >- consumeMarkerAnnotation() ; >- break; >- >- case 717 : if (DEBUG) { System.out.println("SingleMemberAnnotationMemberValue ::= MemberValue"); } //$NON-NLS-1$ >- consumeSingleMemberAnnotationMemberValue() ; >- break; >- >- case 718 : if (DEBUG) { System.out.println("SingleMemberAnnotation ::= AnnotationName LPAREN..."); } //$NON-NLS-1$ >- consumeSingleMemberAnnotation() ; >- break; >- >- case 719 : if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= Modifiersopt TypeParameters"); } //$NON-NLS-1$ >- consumeRecoveryMethodHeaderNameWithTypeParameters(); >- break; >- >- case 720 : if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= Modifiersopt Type..."); } //$NON-NLS-1$ >- consumeRecoveryMethodHeaderName(); >- break; >- >- case 721 : if (DEBUG) { System.out.println("RecoveryMethodHeader ::= RecoveryMethodHeaderName..."); } //$NON-NLS-1$ >- consumeMethodHeader(); >- break; >- >- case 722 : if (DEBUG) { System.out.println("RecoveryMethodHeader ::= RecoveryMethodHeaderName..."); } //$NON-NLS-1$ >- consumeMethodHeader(); >- break; >- >- } >+// This method is part of an automatic generation : do NOT edit-modify >+protected void consumeRule(int act) { >+ switch ( act ) { >+ case 30 : if (DEBUG) { System.out.println("Type ::= PrimitiveType"); } //$NON-NLS-1$ >+ consumePrimitiveType(); >+ break; >+ >+ case 44 : if (DEBUG) { System.out.println("ReferenceType ::= ClassOrInterfaceType"); } //$NON-NLS-1$ >+ consumeReferenceType(); >+ break; >+ >+ case 48 : if (DEBUG) { System.out.println("ClassOrInterface ::= Name"); } //$NON-NLS-1$ >+ consumeClassOrInterfaceName(); >+ break; >+ >+ case 49 : if (DEBUG) { System.out.println("ClassOrInterface ::= GenericType DOT Name"); } //$NON-NLS-1$ >+ consumeClassOrInterface(); >+ break; >+ >+ case 50 : if (DEBUG) { System.out.println("GenericType ::= ClassOrInterface TypeArguments"); } //$NON-NLS-1$ >+ consumeGenericType(); >+ break; >+ >+ case 51 : if (DEBUG) { System.out.println("GenericType ::= ClassOrInterface LESS GREATER"); } //$NON-NLS-1$ >+ consumeGenericTypeWithDiamond(); >+ break; >+ >+ case 52 : if (DEBUG) { System.out.println("ArrayTypeWithTypeArgumentsName ::= GenericType DOT Name"); } //$NON-NLS-1$ >+ consumeArrayTypeWithTypeArgumentsName(); >+ break; >+ >+ case 53 : if (DEBUG) { System.out.println("ArrayType ::= PrimitiveType Dims"); } //$NON-NLS-1$ >+ consumePrimitiveArrayType(); >+ break; >+ >+ case 54 : if (DEBUG) { System.out.println("ArrayType ::= Name Dims"); } //$NON-NLS-1$ >+ consumeNameArrayType(); >+ break; >+ >+ case 55 : if (DEBUG) { System.out.println("ArrayType ::= ArrayTypeWithTypeArgumentsName Dims"); } //$NON-NLS-1$ >+ consumeGenericTypeNameArrayType(); >+ break; >+ >+ case 56 : if (DEBUG) { System.out.println("ArrayType ::= GenericType Dims"); } //$NON-NLS-1$ >+ consumeGenericTypeArrayType(); >+ break; >+ >+ case 61 : if (DEBUG) { System.out.println("QualifiedName ::= Name DOT SimpleName"); } //$NON-NLS-1$ >+ consumeQualifiedName(); >+ break; >+ >+ case 62 : if (DEBUG) { System.out.println("CompilationUnit ::= EnterCompilationUnit..."); } //$NON-NLS-1$ >+ consumeCompilationUnit(); >+ break; >+ >+ case 63 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= PackageDeclaration"); } //$NON-NLS-1$ >+ consumeInternalCompilationUnit(); >+ break; >+ >+ case 64 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= PackageDeclaration..."); } //$NON-NLS-1$ >+ consumeInternalCompilationUnit(); >+ break; >+ >+ case 65 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= PackageDeclaration..."); } //$NON-NLS-1$ >+ consumeInternalCompilationUnitWithTypes(); >+ break; >+ >+ case 66 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= PackageDeclaration..."); } //$NON-NLS-1$ >+ consumeInternalCompilationUnitWithTypes(); >+ break; >+ >+ case 67 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= ImportDeclarations..."); } //$NON-NLS-1$ >+ consumeInternalCompilationUnit(); >+ break; >+ >+ case 68 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= TypeDeclarations"); } //$NON-NLS-1$ >+ consumeInternalCompilationUnitWithTypes(); >+ break; >+ >+ case 69 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= ImportDeclarations..."); } //$NON-NLS-1$ >+ consumeInternalCompilationUnitWithTypes(); >+ break; >+ >+ case 70 : if (DEBUG) { System.out.println("InternalCompilationUnit ::="); } //$NON-NLS-1$ >+ consumeEmptyInternalCompilationUnit(); >+ break; >+ >+ case 71 : if (DEBUG) { System.out.println("ReduceImports ::="); } //$NON-NLS-1$ >+ consumeReduceImports(); >+ break; >+ >+ case 72 : if (DEBUG) { System.out.println("EnterCompilationUnit ::="); } //$NON-NLS-1$ >+ consumeEnterCompilationUnit(); >+ break; >+ >+ case 88 : if (DEBUG) { System.out.println("CatchHeader ::= catch LPAREN CatchFormalParameter RPAREN"); } //$NON-NLS-1$ >+ consumeCatchHeader(); >+ break; >+ >+ case 90 : if (DEBUG) { System.out.println("ImportDeclarations ::= ImportDeclarations..."); } //$NON-NLS-1$ >+ consumeImportDeclarations(); >+ break; >+ >+ case 92 : if (DEBUG) { System.out.println("TypeDeclarations ::= TypeDeclarations TypeDeclaration"); } //$NON-NLS-1$ >+ consumeTypeDeclarations(); >+ break; >+ >+ case 93 : if (DEBUG) { System.out.println("PackageDeclaration ::= PackageDeclarationName SEMICOLON"); } //$NON-NLS-1$ >+ consumePackageDeclaration(); >+ break; >+ >+ case 94 : if (DEBUG) { System.out.println("PackageDeclarationName ::= Modifiers package..."); } //$NON-NLS-1$ >+ consumePackageDeclarationNameWithModifiers(); >+ break; >+ >+ case 95 : if (DEBUG) { System.out.println("PackageDeclarationName ::= PackageComment package Name"); } //$NON-NLS-1$ >+ consumePackageDeclarationName(); >+ break; >+ >+ case 96 : if (DEBUG) { System.out.println("PackageComment ::="); } //$NON-NLS-1$ >+ consumePackageComment(); >+ break; >+ >+ case 101 : if (DEBUG) { System.out.println("SingleTypeImportDeclaration ::=..."); } //$NON-NLS-1$ >+ consumeImportDeclaration(); >+ break; >+ >+ case 102 : if (DEBUG) { System.out.println("SingleTypeImportDeclarationName ::= import Name"); } //$NON-NLS-1$ >+ consumeSingleTypeImportDeclarationName(); >+ break; >+ >+ case 103 : if (DEBUG) { System.out.println("TypeImportOnDemandDeclaration ::=..."); } //$NON-NLS-1$ >+ consumeImportDeclaration(); >+ break; >+ >+ case 104 : if (DEBUG) { System.out.println("TypeImportOnDemandDeclarationName ::= import Name DOT..."); } //$NON-NLS-1$ >+ consumeTypeImportOnDemandDeclarationName(); >+ break; >+ >+ case 107 : if (DEBUG) { System.out.println("TypeDeclaration ::= SEMICOLON"); } //$NON-NLS-1$ >+ consumeEmptyTypeDeclaration(); >+ break; >+ >+ case 111 : if (DEBUG) { System.out.println("Modifiers ::= Modifiers Modifier"); } //$NON-NLS-1$ >+ consumeModifiers2(); >+ break; >+ >+ case 123 : if (DEBUG) { System.out.println("Modifier ::= Annotation"); } //$NON-NLS-1$ >+ consumeAnnotationAsModifier(); >+ break; >+ >+ case 124 : if (DEBUG) { System.out.println("ClassDeclaration ::= ClassHeader ClassBody"); } //$NON-NLS-1$ >+ consumeClassDeclaration(); >+ break; >+ >+ case 125 : if (DEBUG) { System.out.println("ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt..."); } //$NON-NLS-1$ >+ consumeClassHeader(); >+ break; >+ >+ case 126 : if (DEBUG) { System.out.println("ClassHeaderName ::= ClassHeaderName1 TypeParameters"); } //$NON-NLS-1$ >+ consumeTypeHeaderNameWithTypeParameters(); >+ break; >+ >+ case 128 : if (DEBUG) { System.out.println("ClassHeaderName1 ::= Modifiersopt class Identifier"); } //$NON-NLS-1$ >+ consumeClassHeaderName1(); >+ break; >+ >+ case 129 : if (DEBUG) { System.out.println("ClassHeaderExtends ::= extends ClassType"); } //$NON-NLS-1$ >+ consumeClassHeaderExtends(); >+ break; >+ >+ case 130 : if (DEBUG) { System.out.println("ClassHeaderImplements ::= implements InterfaceTypeList"); } //$NON-NLS-1$ >+ consumeClassHeaderImplements(); >+ break; >+ >+ case 132 : if (DEBUG) { System.out.println("InterfaceTypeList ::= InterfaceTypeList COMMA..."); } //$NON-NLS-1$ >+ consumeInterfaceTypeList(); >+ break; >+ >+ case 133 : if (DEBUG) { System.out.println("InterfaceType ::= ClassOrInterfaceType"); } //$NON-NLS-1$ >+ consumeInterfaceType(); >+ break; >+ >+ case 136 : if (DEBUG) { System.out.println("ClassBodyDeclarations ::= ClassBodyDeclarations..."); } //$NON-NLS-1$ >+ consumeClassBodyDeclarations(); >+ break; >+ >+ case 140 : if (DEBUG) { System.out.println("ClassBodyDeclaration ::= Diet NestedMethod..."); } //$NON-NLS-1$ >+ consumeClassBodyDeclaration(); >+ break; >+ >+ case 141 : if (DEBUG) { System.out.println("Diet ::="); } //$NON-NLS-1$ >+ consumeDiet(); >+ break; >+ >+ case 142 : if (DEBUG) { System.out.println("Initializer ::= Diet NestedMethod CreateInitializer..."); } //$NON-NLS-1$ >+ consumeClassBodyDeclaration(); >+ break; >+ >+ case 143 : if (DEBUG) { System.out.println("CreateInitializer ::="); } //$NON-NLS-1$ >+ consumeCreateInitializer(); >+ break; >+ >+ case 150 : if (DEBUG) { System.out.println("ClassMemberDeclaration ::= SEMICOLON"); } //$NON-NLS-1$ >+ consumeEmptyTypeDeclaration(); >+ break; >+ >+ case 153 : if (DEBUG) { System.out.println("FieldDeclaration ::= Modifiersopt Type..."); } //$NON-NLS-1$ >+ consumeFieldDeclaration(); >+ break; >+ >+ case 155 : if (DEBUG) { System.out.println("VariableDeclarators ::= VariableDeclarators COMMA..."); } //$NON-NLS-1$ >+ consumeVariableDeclarators(); >+ break; >+ >+ case 158 : if (DEBUG) { System.out.println("EnterVariable ::="); } //$NON-NLS-1$ >+ consumeEnterVariable(); >+ break; >+ >+ case 159 : if (DEBUG) { System.out.println("ExitVariableWithInitialization ::="); } //$NON-NLS-1$ >+ consumeExitVariableWithInitialization(); >+ break; >+ >+ case 160 : if (DEBUG) { System.out.println("ExitVariableWithoutInitialization ::="); } //$NON-NLS-1$ >+ consumeExitVariableWithoutInitialization(); >+ break; >+ >+ case 161 : if (DEBUG) { System.out.println("ForceNoDiet ::="); } //$NON-NLS-1$ >+ consumeForceNoDiet(); >+ break; >+ >+ case 162 : if (DEBUG) { System.out.println("RestoreDiet ::="); } //$NON-NLS-1$ >+ consumeRestoreDiet(); >+ break; >+ >+ case 167 : if (DEBUG) { System.out.println("MethodDeclaration ::= MethodHeader MethodBody"); } //$NON-NLS-1$ >+ // set to true to consume a method with a body >+ consumeMethodDeclaration(true); >+ break; >+ >+ case 168 : if (DEBUG) { System.out.println("AbstractMethodDeclaration ::= MethodHeader SEMICOLON"); } //$NON-NLS-1$ >+ // set to false to consume a method without body >+ consumeMethodDeclaration(false); >+ break; >+ >+ case 169 : if (DEBUG) { System.out.println("MethodHeader ::= MethodHeaderName FormalParameterListopt"); } //$NON-NLS-1$ >+ consumeMethodHeader(); >+ break; >+ >+ case 170 : if (DEBUG) { System.out.println("MethodHeaderName ::= Modifiersopt TypeParameters Type..."); } //$NON-NLS-1$ >+ consumeMethodHeaderNameWithTypeParameters(false); >+ break; >+ >+ case 171 : if (DEBUG) { System.out.println("MethodHeaderName ::= Modifiersopt Type Identifier LPAREN"); } //$NON-NLS-1$ >+ consumeMethodHeaderName(false); >+ break; >+ >+ case 172 : if (DEBUG) { System.out.println("MethodHeaderRightParen ::= RPAREN"); } //$NON-NLS-1$ >+ consumeMethodHeaderRightParen(); >+ break; >+ >+ case 173 : if (DEBUG) { System.out.println("MethodHeaderExtendedDims ::= Dimsopt"); } //$NON-NLS-1$ >+ consumeMethodHeaderExtendedDims(); >+ break; >+ >+ case 174 : if (DEBUG) { System.out.println("MethodHeaderThrowsClause ::= throws ClassTypeList"); } //$NON-NLS-1$ >+ consumeMethodHeaderThrowsClause(); >+ break; >+ >+ case 175 : if (DEBUG) { System.out.println("ConstructorHeader ::= ConstructorHeaderName..."); } //$NON-NLS-1$ >+ consumeConstructorHeader(); >+ break; >+ >+ case 176 : if (DEBUG) { System.out.println("ConstructorHeaderName ::= Modifiersopt TypeParameters..."); } //$NON-NLS-1$ >+ consumeConstructorHeaderNameWithTypeParameters(); >+ break; >+ >+ case 177 : if (DEBUG) { System.out.println("ConstructorHeaderName ::= Modifiersopt Identifier LPAREN"); } //$NON-NLS-1$ >+ consumeConstructorHeaderName(); >+ break; >+ >+ case 179 : if (DEBUG) { System.out.println("FormalParameterList ::= FormalParameterList COMMA..."); } //$NON-NLS-1$ >+ consumeFormalParameterList(); >+ break; >+ >+ case 180 : if (DEBUG) { System.out.println("FormalParameter ::= Modifiersopt Type..."); } //$NON-NLS-1$ >+ consumeFormalParameter(false); >+ break; >+ >+ case 181 : if (DEBUG) { System.out.println("FormalParameter ::= Modifiersopt Type ELLIPSIS..."); } //$NON-NLS-1$ >+ consumeFormalParameter(true); >+ break; >+ >+ case 182 : if (DEBUG) { System.out.println("CatchFormalParameter ::= Modifiersopt CatchType..."); } //$NON-NLS-1$ >+ consumeCatchFormalParameter(); >+ break; >+ >+ case 183 : if (DEBUG) { System.out.println("CatchType ::= UnionType"); } //$NON-NLS-1$ >+ consumeCatchType(); >+ break; >+ >+ case 184 : if (DEBUG) { System.out.println("UnionType ::= Type"); } //$NON-NLS-1$ >+ consumeUnionTypeAsClassType(); >+ break; >+ >+ case 185 : if (DEBUG) { System.out.println("UnionType ::= UnionType OR Type"); } //$NON-NLS-1$ >+ consumeUnionType(); >+ break; >+ >+ case 187 : if (DEBUG) { System.out.println("ClassTypeList ::= ClassTypeList COMMA ClassTypeElt"); } //$NON-NLS-1$ >+ consumeClassTypeList(); >+ break; >+ >+ case 188 : if (DEBUG) { System.out.println("ClassTypeElt ::= ClassType"); } //$NON-NLS-1$ >+ consumeClassTypeElt(); >+ break; >+ >+ case 189 : if (DEBUG) { System.out.println("MethodBody ::= NestedMethod LBRACE BlockStatementsopt..."); } //$NON-NLS-1$ >+ consumeMethodBody(); >+ break; >+ >+ case 190 : if (DEBUG) { System.out.println("NestedMethod ::="); } //$NON-NLS-1$ >+ consumeNestedMethod(); >+ break; >+ >+ case 191 : if (DEBUG) { System.out.println("StaticInitializer ::= StaticOnly Block"); } //$NON-NLS-1$ >+ consumeStaticInitializer(); >+ break; >+ >+ case 192 : if (DEBUG) { System.out.println("StaticOnly ::= static"); } //$NON-NLS-1$ >+ consumeStaticOnly(); >+ break; >+ >+ case 193 : if (DEBUG) { System.out.println("ConstructorDeclaration ::= ConstructorHeader MethodBody"); } //$NON-NLS-1$ >+ consumeConstructorDeclaration() ; >+ break; >+ >+ case 194 : if (DEBUG) { System.out.println("ConstructorDeclaration ::= ConstructorHeader SEMICOLON"); } //$NON-NLS-1$ >+ consumeInvalidConstructorDeclaration() ; >+ break; >+ >+ case 195 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= this LPAREN..."); } //$NON-NLS-1$ >+ consumeExplicitConstructorInvocation(0, THIS_CALL); >+ break; >+ >+ case 196 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= OnlyTypeArguments this"); } //$NON-NLS-1$ >+ consumeExplicitConstructorInvocationWithTypeArguments(0,THIS_CALL); >+ break; >+ >+ case 197 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= super LPAREN..."); } //$NON-NLS-1$ >+ consumeExplicitConstructorInvocation(0,SUPER_CALL); >+ break; >+ >+ case 198 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= OnlyTypeArguments..."); } //$NON-NLS-1$ >+ consumeExplicitConstructorInvocationWithTypeArguments(0,SUPER_CALL); >+ break; >+ >+ case 199 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Primary DOT super..."); } //$NON-NLS-1$ >+ consumeExplicitConstructorInvocation(1, SUPER_CALL); >+ break; >+ >+ case 200 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Primary DOT..."); } //$NON-NLS-1$ >+ consumeExplicitConstructorInvocationWithTypeArguments(1, SUPER_CALL); >+ break; >+ >+ case 201 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT super LPAREN"); } //$NON-NLS-1$ >+ consumeExplicitConstructorInvocation(2, SUPER_CALL); >+ break; >+ >+ case 202 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT..."); } //$NON-NLS-1$ >+ consumeExplicitConstructorInvocationWithTypeArguments(2, SUPER_CALL); >+ break; >+ >+ case 203 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Primary DOT this..."); } //$NON-NLS-1$ >+ consumeExplicitConstructorInvocation(1, THIS_CALL); >+ break; >+ >+ case 204 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Primary DOT..."); } //$NON-NLS-1$ >+ consumeExplicitConstructorInvocationWithTypeArguments(1, THIS_CALL); >+ break; >+ >+ case 205 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT this LPAREN"); } //$NON-NLS-1$ >+ consumeExplicitConstructorInvocation(2, THIS_CALL); >+ break; >+ >+ case 206 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT..."); } //$NON-NLS-1$ >+ consumeExplicitConstructorInvocationWithTypeArguments(2, THIS_CALL); >+ break; >+ >+ case 207 : if (DEBUG) { System.out.println("InterfaceDeclaration ::= InterfaceHeader InterfaceBody"); } //$NON-NLS-1$ >+ consumeInterfaceDeclaration(); >+ break; >+ >+ case 208 : if (DEBUG) { System.out.println("InterfaceHeader ::= InterfaceHeaderName..."); } //$NON-NLS-1$ >+ consumeInterfaceHeader(); >+ break; >+ >+ case 209 : if (DEBUG) { System.out.println("InterfaceHeaderName ::= InterfaceHeaderName1..."); } //$NON-NLS-1$ >+ consumeTypeHeaderNameWithTypeParameters(); >+ break; >+ >+ case 211 : if (DEBUG) { System.out.println("InterfaceHeaderName1 ::= Modifiersopt interface..."); } //$NON-NLS-1$ >+ consumeInterfaceHeaderName1(); >+ break; >+ >+ case 212 : if (DEBUG) { System.out.println("InterfaceHeaderExtends ::= extends InterfaceTypeList"); } //$NON-NLS-1$ >+ consumeInterfaceHeaderExtends(); >+ break; >+ >+ case 215 : if (DEBUG) { System.out.println("InterfaceMemberDeclarations ::=..."); } //$NON-NLS-1$ >+ consumeInterfaceMemberDeclarations(); >+ break; >+ >+ case 216 : if (DEBUG) { System.out.println("InterfaceMemberDeclaration ::= SEMICOLON"); } //$NON-NLS-1$ >+ consumeEmptyTypeDeclaration(); >+ break; >+ >+ case 218 : if (DEBUG) { System.out.println("InterfaceMemberDeclaration ::= MethodHeader MethodBody"); } //$NON-NLS-1$ >+ consumeInvalidMethodDeclaration(); >+ break; >+ >+ case 219 : if (DEBUG) { System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader..."); } //$NON-NLS-1$ >+ consumeInvalidConstructorDeclaration(true); >+ break; >+ >+ case 220 : if (DEBUG) { System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader..."); } //$NON-NLS-1$ >+ consumeInvalidConstructorDeclaration(false); >+ break; >+ >+ case 231 : if (DEBUG) { System.out.println("PushLeftBrace ::="); } //$NON-NLS-1$ >+ consumePushLeftBrace(); >+ break; >+ >+ case 232 : if (DEBUG) { System.out.println("ArrayInitializer ::= LBRACE PushLeftBrace ,opt RBRACE"); } //$NON-NLS-1$ >+ consumeEmptyArrayInitializer(); >+ break; >+ >+ case 233 : if (DEBUG) { System.out.println("ArrayInitializer ::= LBRACE PushLeftBrace..."); } //$NON-NLS-1$ >+ consumeArrayInitializer(); >+ break; >+ >+ case 234 : if (DEBUG) { System.out.println("ArrayInitializer ::= LBRACE PushLeftBrace..."); } //$NON-NLS-1$ >+ consumeArrayInitializer(); >+ break; >+ >+ case 236 : if (DEBUG) { System.out.println("VariableInitializers ::= VariableInitializers COMMA..."); } //$NON-NLS-1$ >+ consumeVariableInitializers(); >+ break; >+ >+ case 237 : if (DEBUG) { System.out.println("Block ::= OpenBlock LBRACE BlockStatementsopt RBRACE"); } //$NON-NLS-1$ >+ consumeBlock(); >+ break; >+ >+ case 238 : if (DEBUG) { System.out.println("OpenBlock ::="); } //$NON-NLS-1$ >+ consumeOpenBlock() ; >+ break; >+ >+ case 240 : if (DEBUG) { System.out.println("BlockStatements ::= BlockStatements BlockStatement"); } //$NON-NLS-1$ >+ consumeBlockStatements() ; >+ break; >+ >+ case 244 : if (DEBUG) { System.out.println("BlockStatement ::= InterfaceDeclaration"); } //$NON-NLS-1$ >+ consumeInvalidInterfaceDeclaration(); >+ break; >+ >+ case 245 : if (DEBUG) { System.out.println("BlockStatement ::= AnnotationTypeDeclaration"); } //$NON-NLS-1$ >+ consumeInvalidAnnotationTypeDeclaration(); >+ break; >+ >+ case 246 : if (DEBUG) { System.out.println("BlockStatement ::= EnumDeclaration"); } //$NON-NLS-1$ >+ consumeInvalidEnumDeclaration(); >+ break; >+ >+ case 247 : if (DEBUG) { System.out.println("LocalVariableDeclarationStatement ::=..."); } //$NON-NLS-1$ >+ consumeLocalVariableDeclarationStatement(); >+ break; >+ >+ case 248 : if (DEBUG) { System.out.println("LocalVariableDeclaration ::= Type PushModifiers..."); } //$NON-NLS-1$ >+ consumeLocalVariableDeclaration(); >+ break; >+ >+ case 249 : if (DEBUG) { System.out.println("LocalVariableDeclaration ::= Modifiers Type..."); } //$NON-NLS-1$ >+ consumeLocalVariableDeclaration(); >+ break; >+ >+ case 250 : if (DEBUG) { System.out.println("PushModifiers ::="); } //$NON-NLS-1$ >+ consumePushModifiers(); >+ break; >+ >+ case 251 : if (DEBUG) { System.out.println("PushModifiersForHeader ::="); } //$NON-NLS-1$ >+ consumePushModifiersForHeader(); >+ break; >+ >+ case 252 : if (DEBUG) { System.out.println("PushRealModifiers ::="); } //$NON-NLS-1$ >+ consumePushRealModifiers(); >+ break; >+ >+ case 279 : if (DEBUG) { System.out.println("EmptyStatement ::= SEMICOLON"); } //$NON-NLS-1$ >+ consumeEmptyStatement(); >+ break; >+ >+ case 280 : if (DEBUG) { System.out.println("LabeledStatement ::= Label COLON Statement"); } //$NON-NLS-1$ >+ consumeStatementLabel() ; >+ break; >+ >+ case 281 : if (DEBUG) { System.out.println("LabeledStatementNoShortIf ::= Label COLON..."); } //$NON-NLS-1$ >+ consumeStatementLabel() ; >+ break; >+ >+ case 282 : if (DEBUG) { System.out.println("Label ::= Identifier"); } //$NON-NLS-1$ >+ consumeLabel() ; >+ break; >+ >+ case 283 : if (DEBUG) { System.out.println("ExpressionStatement ::= StatementExpression SEMICOLON"); } //$NON-NLS-1$ >+ consumeExpressionStatement(); >+ break; >+ >+ case 292 : if (DEBUG) { System.out.println("IfThenStatement ::= if LPAREN Expression RPAREN..."); } //$NON-NLS-1$ >+ consumeStatementIfNoElse(); >+ break; >+ >+ case 293 : if (DEBUG) { System.out.println("IfThenElseStatement ::= if LPAREN Expression RPAREN..."); } //$NON-NLS-1$ >+ consumeStatementIfWithElse(); >+ break; >+ >+ case 294 : if (DEBUG) { System.out.println("IfThenElseStatementNoShortIf ::= if LPAREN Expression..."); } //$NON-NLS-1$ >+ consumeStatementIfWithElse(); >+ break; >+ >+ case 295 : if (DEBUG) { System.out.println("SwitchStatement ::= switch LPAREN Expression RPAREN..."); } //$NON-NLS-1$ >+ consumeStatementSwitch() ; >+ break; >+ >+ case 296 : if (DEBUG) { System.out.println("SwitchBlock ::= LBRACE RBRACE"); } //$NON-NLS-1$ >+ consumeEmptySwitchBlock() ; >+ break; >+ >+ case 299 : if (DEBUG) { System.out.println("SwitchBlock ::= LBRACE SwitchBlockStatements..."); } //$NON-NLS-1$ >+ consumeSwitchBlock() ; >+ break; >+ >+ case 301 : if (DEBUG) { System.out.println("SwitchBlockStatements ::= SwitchBlockStatements..."); } //$NON-NLS-1$ >+ consumeSwitchBlockStatements() ; >+ break; >+ >+ case 302 : if (DEBUG) { System.out.println("SwitchBlockStatement ::= SwitchLabels BlockStatements"); } //$NON-NLS-1$ >+ consumeSwitchBlockStatement() ; >+ break; >+ >+ case 304 : if (DEBUG) { System.out.println("SwitchLabels ::= SwitchLabels SwitchLabel"); } //$NON-NLS-1$ >+ consumeSwitchLabels() ; >+ break; >+ >+ case 305 : if (DEBUG) { System.out.println("SwitchLabel ::= case ConstantExpression COLON"); } //$NON-NLS-1$ >+ consumeCaseLabel(); >+ break; >+ >+ case 306 : if (DEBUG) { System.out.println("SwitchLabel ::= default COLON"); } //$NON-NLS-1$ >+ consumeDefaultLabel(); >+ break; >+ >+ case 307 : if (DEBUG) { System.out.println("WhileStatement ::= while LPAREN Expression RPAREN..."); } //$NON-NLS-1$ >+ consumeStatementWhile() ; >+ break; >+ >+ case 308 : if (DEBUG) { System.out.println("WhileStatementNoShortIf ::= while LPAREN Expression..."); } //$NON-NLS-1$ >+ consumeStatementWhile() ; >+ break; >+ >+ case 309 : if (DEBUG) { System.out.println("DoStatement ::= do Statement while LPAREN Expression..."); } //$NON-NLS-1$ >+ consumeStatementDo() ; >+ break; >+ >+ case 310 : if (DEBUG) { System.out.println("ForStatement ::= for LPAREN ForInitopt SEMICOLON..."); } //$NON-NLS-1$ >+ consumeStatementFor() ; >+ break; >+ >+ case 311 : if (DEBUG) { System.out.println("ForStatementNoShortIf ::= for LPAREN ForInitopt..."); } //$NON-NLS-1$ >+ consumeStatementFor() ; >+ break; >+ >+ case 312 : if (DEBUG) { System.out.println("ForInit ::= StatementExpressionList"); } //$NON-NLS-1$ >+ consumeForInit() ; >+ break; >+ >+ case 316 : if (DEBUG) { System.out.println("StatementExpressionList ::= StatementExpressionList..."); } //$NON-NLS-1$ >+ consumeStatementExpressionList() ; >+ break; >+ >+ case 317 : if (DEBUG) { System.out.println("AssertStatement ::= assert Expression SEMICOLON"); } //$NON-NLS-1$ >+ consumeSimpleAssertStatement() ; >+ break; >+ >+ case 318 : if (DEBUG) { System.out.println("AssertStatement ::= assert Expression COLON Expression"); } //$NON-NLS-1$ >+ consumeAssertStatement() ; >+ break; >+ >+ case 319 : if (DEBUG) { System.out.println("BreakStatement ::= break SEMICOLON"); } //$NON-NLS-1$ >+ consumeStatementBreak() ; >+ break; >+ >+ case 320 : if (DEBUG) { System.out.println("BreakStatement ::= break Identifier SEMICOLON"); } //$NON-NLS-1$ >+ consumeStatementBreakWithLabel() ; >+ break; >+ >+ case 321 : if (DEBUG) { System.out.println("ContinueStatement ::= continue SEMICOLON"); } //$NON-NLS-1$ >+ consumeStatementContinue() ; >+ break; >+ >+ case 322 : if (DEBUG) { System.out.println("ContinueStatement ::= continue Identifier SEMICOLON"); } //$NON-NLS-1$ >+ consumeStatementContinueWithLabel() ; >+ break; >+ >+ case 323 : if (DEBUG) { System.out.println("ReturnStatement ::= return Expressionopt SEMICOLON"); } //$NON-NLS-1$ >+ consumeStatementReturn() ; >+ break; >+ >+ case 324 : if (DEBUG) { System.out.println("ThrowStatement ::= throw Expression SEMICOLON"); } //$NON-NLS-1$ >+ consumeStatementThrow(); >+ break; >+ >+ case 325 : if (DEBUG) { System.out.println("SynchronizedStatement ::= OnlySynchronized LPAREN..."); } //$NON-NLS-1$ >+ consumeStatementSynchronized(); >+ break; >+ >+ case 326 : if (DEBUG) { System.out.println("OnlySynchronized ::= synchronized"); } //$NON-NLS-1$ >+ consumeOnlySynchronized(); >+ break; >+ >+ case 327 : if (DEBUG) { System.out.println("TryStatement ::= try TryBlock Catches"); } //$NON-NLS-1$ >+ consumeStatementTry(false, false); >+ break; >+ >+ case 328 : if (DEBUG) { System.out.println("TryStatement ::= try TryBlock Catchesopt Finally"); } //$NON-NLS-1$ >+ consumeStatementTry(true, false); >+ break; >+ >+ case 329 : if (DEBUG) { System.out.println("TryStatementWithResources ::= try ResourceSpecification"); } //$NON-NLS-1$ >+ consumeStatementTry(false, true); >+ break; >+ >+ case 330 : if (DEBUG) { System.out.println("TryStatementWithResources ::= try ResourceSpecification"); } //$NON-NLS-1$ >+ consumeStatementTry(true, true); >+ break; >+ >+ case 331 : if (DEBUG) { System.out.println("ResourceSpecification ::= LPAREN Resources ;opt RPAREN"); } //$NON-NLS-1$ >+ consumeResourceSpecification(); >+ break; >+ >+ case 332 : if (DEBUG) { System.out.println(";opt ::="); } //$NON-NLS-1$ >+ consumeResourceOptionalTrailingSemiColon(false); >+ break; >+ >+ case 333 : if (DEBUG) { System.out.println(";opt ::= SEMICOLON"); } //$NON-NLS-1$ >+ consumeResourceOptionalTrailingSemiColon(true); >+ break; >+ >+ case 334 : if (DEBUG) { System.out.println("Resources ::= Resource"); } //$NON-NLS-1$ >+ consumeSingleResource(); >+ break; >+ >+ case 335 : if (DEBUG) { System.out.println("Resources ::= Resources TrailingSemiColon Resource"); } //$NON-NLS-1$ >+ consumeMultipleResources(); >+ break; >+ >+ case 336 : if (DEBUG) { System.out.println("TrailingSemiColon ::= SEMICOLON"); } //$NON-NLS-1$ >+ consumeResourceOptionalTrailingSemiColon(true); >+ break; >+ >+ case 337 : if (DEBUG) { System.out.println("Resource ::= Type PushModifiers VariableDeclaratorId..."); } //$NON-NLS-1$ >+ consumeResourceAsLocalVariableDeclaration(); >+ break; >+ >+ case 338 : if (DEBUG) { System.out.println("Resource ::= Modifiers Type PushRealModifiers..."); } //$NON-NLS-1$ >+ consumeResourceAsLocalVariableDeclaration(); >+ break; >+ >+ case 340 : if (DEBUG) { System.out.println("ExitTryBlock ::="); } //$NON-NLS-1$ >+ consumeExitTryBlock(); >+ break; >+ >+ case 342 : if (DEBUG) { System.out.println("Catches ::= Catches CatchClause"); } //$NON-NLS-1$ >+ consumeCatches(); >+ break; >+ >+ case 343 : if (DEBUG) { System.out.println("CatchClause ::= catch LPAREN CatchFormalParameter RPAREN"); } //$NON-NLS-1$ >+ consumeStatementCatch() ; >+ break; >+ >+ case 345 : if (DEBUG) { System.out.println("PushLPAREN ::= LPAREN"); } //$NON-NLS-1$ >+ consumeLeftParen(); >+ break; >+ >+ case 346 : if (DEBUG) { System.out.println("PushRPAREN ::= RPAREN"); } //$NON-NLS-1$ >+ consumeRightParen(); >+ break; >+ >+ case 351 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= this"); } //$NON-NLS-1$ >+ consumePrimaryNoNewArrayThis(); >+ break; >+ >+ case 352 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PushLPAREN Expression_NotName..."); } //$NON-NLS-1$ >+ consumePrimaryNoNewArray(); >+ break; >+ >+ case 353 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PushLPAREN Name PushRPAREN"); } //$NON-NLS-1$ >+ consumePrimaryNoNewArrayWithName(); >+ break; >+ >+ case 356 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT this"); } //$NON-NLS-1$ >+ consumePrimaryNoNewArrayNameThis(); >+ break; >+ >+ case 357 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT super"); } //$NON-NLS-1$ >+ consumePrimaryNoNewArrayNameSuper(); >+ break; >+ >+ case 358 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT class"); } //$NON-NLS-1$ >+ consumePrimaryNoNewArrayName(); >+ break; >+ >+ case 359 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name Dims DOT class"); } //$NON-NLS-1$ >+ consumePrimaryNoNewArrayArrayType(); >+ break; >+ >+ case 360 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PrimitiveType Dims DOT class"); } //$NON-NLS-1$ >+ consumePrimaryNoNewArrayPrimitiveArrayType(); >+ break; >+ >+ case 361 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PrimitiveType DOT class"); } //$NON-NLS-1$ >+ consumePrimaryNoNewArrayPrimitiveType(); >+ break; >+ >+ case 364 : if (DEBUG) { System.out.println("AllocationHeader ::= new ClassType LPAREN..."); } //$NON-NLS-1$ >+ consumeAllocationHeader(); >+ break; >+ >+ case 365 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= new..."); } //$NON-NLS-1$ >+ consumeClassInstanceCreationExpressionWithTypeArguments(); >+ break; >+ >+ case 366 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= new ClassType..."); } //$NON-NLS-1$ >+ consumeClassInstanceCreationExpression(); >+ break; >+ >+ case 367 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= Primary DOT new..."); } //$NON-NLS-1$ >+ consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() ; >+ break; >+ >+ case 368 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= Primary DOT new..."); } //$NON-NLS-1$ >+ consumeClassInstanceCreationExpressionQualified() ; >+ break; >+ >+ case 369 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::=..."); } //$NON-NLS-1$ >+ consumeClassInstanceCreationExpressionQualified() ; >+ break; >+ >+ case 370 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::=..."); } //$NON-NLS-1$ >+ consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() ; >+ break; >+ >+ case 371 : if (DEBUG) { System.out.println("EnterInstanceCreationArgumentList ::="); } //$NON-NLS-1$ >+ consumeEnterInstanceCreationArgumentList(); >+ break; >+ >+ case 372 : if (DEBUG) { System.out.println("ClassInstanceCreationExpressionName ::= Name DOT"); } //$NON-NLS-1$ >+ consumeClassInstanceCreationExpressionName() ; >+ break; >+ >+ case 373 : if (DEBUG) { System.out.println("UnqualifiedClassBodyopt ::="); } //$NON-NLS-1$ >+ consumeClassBodyopt(); >+ break; >+ >+ case 375 : if (DEBUG) { System.out.println("UnqualifiedEnterAnonymousClassBody ::="); } //$NON-NLS-1$ >+ consumeEnterAnonymousClassBody(false); >+ break; >+ >+ case 376 : if (DEBUG) { System.out.println("QualifiedClassBodyopt ::="); } //$NON-NLS-1$ >+ consumeClassBodyopt(); >+ break; >+ >+ case 378 : if (DEBUG) { System.out.println("QualifiedEnterAnonymousClassBody ::="); } //$NON-NLS-1$ >+ consumeEnterAnonymousClassBody(true); >+ break; >+ >+ case 380 : if (DEBUG) { System.out.println("ArgumentList ::= ArgumentList COMMA Expression"); } //$NON-NLS-1$ >+ consumeArgumentList(); >+ break; >+ >+ case 381 : if (DEBUG) { System.out.println("ArrayCreationHeader ::= new PrimitiveType..."); } //$NON-NLS-1$ >+ consumeArrayCreationHeader(); >+ break; >+ >+ case 382 : if (DEBUG) { System.out.println("ArrayCreationHeader ::= new ClassOrInterfaceType..."); } //$NON-NLS-1$ >+ consumeArrayCreationHeader(); >+ break; >+ >+ case 383 : if (DEBUG) { System.out.println("ArrayCreationWithoutArrayInitializer ::= new..."); } //$NON-NLS-1$ >+ consumeArrayCreationExpressionWithoutInitializer(); >+ break; >+ >+ case 384 : if (DEBUG) { System.out.println("ArrayCreationWithArrayInitializer ::= new PrimitiveType"); } //$NON-NLS-1$ >+ consumeArrayCreationExpressionWithInitializer(); >+ break; >+ >+ case 385 : if (DEBUG) { System.out.println("ArrayCreationWithoutArrayInitializer ::= new..."); } //$NON-NLS-1$ >+ consumeArrayCreationExpressionWithoutInitializer(); >+ break; >+ >+ case 386 : if (DEBUG) { System.out.println("ArrayCreationWithArrayInitializer ::= new..."); } //$NON-NLS-1$ >+ consumeArrayCreationExpressionWithInitializer(); >+ break; >+ >+ case 388 : if (DEBUG) { System.out.println("DimWithOrWithOutExprs ::= DimWithOrWithOutExprs..."); } //$NON-NLS-1$ >+ consumeDimWithOrWithOutExprs(); >+ break; >+ >+ case 390 : if (DEBUG) { System.out.println("DimWithOrWithOutExpr ::= LBRACKET RBRACKET"); } //$NON-NLS-1$ >+ consumeDimWithOrWithOutExpr(); >+ break; >+ >+ case 391 : if (DEBUG) { System.out.println("Dims ::= DimsLoop"); } //$NON-NLS-1$ >+ consumeDims(); >+ break; >+ >+ case 394 : if (DEBUG) { System.out.println("OneDimLoop ::= LBRACKET RBRACKET"); } //$NON-NLS-1$ >+ consumeOneDimLoop(); >+ break; >+ >+ case 395 : if (DEBUG) { System.out.println("FieldAccess ::= Primary DOT Identifier"); } //$NON-NLS-1$ >+ consumeFieldAccess(false); >+ break; >+ >+ case 396 : if (DEBUG) { System.out.println("FieldAccess ::= super DOT Identifier"); } //$NON-NLS-1$ >+ consumeFieldAccess(true); >+ break; >+ >+ case 397 : if (DEBUG) { System.out.println("MethodInvocation ::= Name LPAREN ArgumentListopt RPAREN"); } //$NON-NLS-1$ >+ consumeMethodInvocationName(); >+ break; >+ >+ case 398 : if (DEBUG) { System.out.println("MethodInvocation ::= Name DOT OnlyTypeArguments..."); } //$NON-NLS-1$ >+ consumeMethodInvocationNameWithTypeArguments(); >+ break; >+ >+ case 399 : if (DEBUG) { System.out.println("MethodInvocation ::= Primary DOT OnlyTypeArguments..."); } //$NON-NLS-1$ >+ consumeMethodInvocationPrimaryWithTypeArguments(); >+ break; >+ >+ case 400 : if (DEBUG) { System.out.println("MethodInvocation ::= Primary DOT Identifier LPAREN..."); } //$NON-NLS-1$ >+ consumeMethodInvocationPrimary(); >+ break; >+ >+ case 401 : if (DEBUG) { System.out.println("MethodInvocation ::= super DOT OnlyTypeArguments..."); } //$NON-NLS-1$ >+ consumeMethodInvocationSuperWithTypeArguments(); >+ break; >+ >+ case 402 : if (DEBUG) { System.out.println("MethodInvocation ::= super DOT Identifier LPAREN..."); } //$NON-NLS-1$ >+ consumeMethodInvocationSuper(); >+ break; >+ >+ case 403 : if (DEBUG) { System.out.println("ArrayAccess ::= Name LBRACKET Expression RBRACKET"); } //$NON-NLS-1$ >+ consumeArrayAccess(true); >+ break; >+ >+ case 404 : if (DEBUG) { System.out.println("ArrayAccess ::= PrimaryNoNewArray LBRACKET Expression..."); } //$NON-NLS-1$ >+ consumeArrayAccess(false); >+ break; >+ >+ case 405 : if (DEBUG) { System.out.println("ArrayAccess ::= ArrayCreationWithArrayInitializer..."); } //$NON-NLS-1$ >+ consumeArrayAccess(false); >+ break; >+ >+ case 407 : if (DEBUG) { System.out.println("PostfixExpression ::= Name"); } //$NON-NLS-1$ >+ consumePostfixExpression(); >+ break; >+ >+ case 410 : if (DEBUG) { System.out.println("PostIncrementExpression ::= PostfixExpression PLUS_PLUS"); } //$NON-NLS-1$ >+ consumeUnaryExpression(OperatorIds.PLUS,true); >+ break; >+ >+ case 411 : if (DEBUG) { System.out.println("PostDecrementExpression ::= PostfixExpression..."); } //$NON-NLS-1$ >+ consumeUnaryExpression(OperatorIds.MINUS,true); >+ break; >+ >+ case 412 : if (DEBUG) { System.out.println("PushPosition ::="); } //$NON-NLS-1$ >+ consumePushPosition(); >+ break; >+ >+ case 415 : if (DEBUG) { System.out.println("UnaryExpression ::= PLUS PushPosition UnaryExpression"); } //$NON-NLS-1$ >+ consumeUnaryExpression(OperatorIds.PLUS); >+ break; >+ >+ case 416 : if (DEBUG) { System.out.println("UnaryExpression ::= MINUS PushPosition UnaryExpression"); } //$NON-NLS-1$ >+ consumeUnaryExpression(OperatorIds.MINUS); >+ break; >+ >+ case 418 : if (DEBUG) { System.out.println("PreIncrementExpression ::= PLUS_PLUS PushPosition..."); } //$NON-NLS-1$ >+ consumeUnaryExpression(OperatorIds.PLUS,false); >+ break; >+ >+ case 419 : if (DEBUG) { System.out.println("PreDecrementExpression ::= MINUS_MINUS PushPosition..."); } //$NON-NLS-1$ >+ consumeUnaryExpression(OperatorIds.MINUS,false); >+ break; >+ >+ case 421 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus ::= TWIDDLE PushPosition..."); } //$NON-NLS-1$ >+ consumeUnaryExpression(OperatorIds.TWIDDLE); >+ break; >+ >+ case 422 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus ::= NOT PushPosition..."); } //$NON-NLS-1$ >+ consumeUnaryExpression(OperatorIds.NOT); >+ break; >+ >+ case 424 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN PrimitiveType Dimsopt..."); } //$NON-NLS-1$ >+ consumeCastExpressionWithPrimitiveType(); >+ break; >+ >+ case 425 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name..."); } //$NON-NLS-1$ >+ consumeCastExpressionWithGenericsArray(); >+ break; >+ >+ case 426 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name..."); } //$NON-NLS-1$ >+ consumeCastExpressionWithQualifiedGenericsArray(); >+ break; >+ >+ case 427 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name PushRPAREN..."); } //$NON-NLS-1$ >+ consumeCastExpressionLL1(); >+ break; >+ >+ case 428 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name Dims PushRPAREN..."); } //$NON-NLS-1$ >+ consumeCastExpressionWithNameArray(); >+ break; >+ >+ case 429 : if (DEBUG) { System.out.println("OnlyTypeArgumentsForCastExpression ::= OnlyTypeArguments"); } //$NON-NLS-1$ >+ consumeOnlyTypeArgumentsForCastExpression(); >+ break; >+ >+ case 430 : if (DEBUG) { System.out.println("InsideCastExpression ::="); } //$NON-NLS-1$ >+ consumeInsideCastExpression(); >+ break; >+ >+ case 431 : if (DEBUG) { System.out.println("InsideCastExpressionLL1 ::="); } //$NON-NLS-1$ >+ consumeInsideCastExpressionLL1(); >+ break; >+ >+ case 432 : if (DEBUG) { System.out.println("InsideCastExpressionWithQualifiedGenerics ::="); } //$NON-NLS-1$ >+ consumeInsideCastExpressionWithQualifiedGenerics(); >+ break; >+ >+ case 434 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.MULTIPLY); >+ break; >+ >+ case 435 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.DIVIDE); >+ break; >+ >+ case 436 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.REMAINDER); >+ break; >+ >+ case 438 : if (DEBUG) { System.out.println("AdditiveExpression ::= AdditiveExpression PLUS..."); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.PLUS); >+ break; >+ >+ case 439 : if (DEBUG) { System.out.println("AdditiveExpression ::= AdditiveExpression MINUS..."); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.MINUS); >+ break; >+ >+ case 441 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression LEFT_SHIFT..."); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.LEFT_SHIFT); >+ break; >+ >+ case 442 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression RIGHT_SHIFT..."); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.RIGHT_SHIFT); >+ break; >+ >+ case 443 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression UNSIGNED_RIGHT_SHIFT"); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.UNSIGNED_RIGHT_SHIFT); >+ break; >+ >+ case 445 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS..."); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.LESS); >+ break; >+ >+ case 446 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression GREATER..."); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.GREATER); >+ break; >+ >+ case 447 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS_EQUAL"); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.LESS_EQUAL); >+ break; >+ >+ case 448 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression..."); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.GREATER_EQUAL); >+ break; >+ >+ case 450 : if (DEBUG) { System.out.println("InstanceofExpression ::= InstanceofExpression instanceof"); } //$NON-NLS-1$ >+ consumeInstanceOfExpression(); >+ break; >+ >+ case 452 : if (DEBUG) { System.out.println("EqualityExpression ::= EqualityExpression EQUAL_EQUAL..."); } //$NON-NLS-1$ >+ consumeEqualityExpression(OperatorIds.EQUAL_EQUAL); >+ break; >+ >+ case 453 : if (DEBUG) { System.out.println("EqualityExpression ::= EqualityExpression NOT_EQUAL..."); } //$NON-NLS-1$ >+ consumeEqualityExpression(OperatorIds.NOT_EQUAL); >+ break; >+ >+ case 455 : if (DEBUG) { System.out.println("AndExpression ::= AndExpression AND EqualityExpression"); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.AND); >+ break; >+ >+ case 457 : if (DEBUG) { System.out.println("ExclusiveOrExpression ::= ExclusiveOrExpression XOR..."); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.XOR); >+ break; >+ >+ case 459 : if (DEBUG) { System.out.println("InclusiveOrExpression ::= InclusiveOrExpression OR..."); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.OR); >+ break; >+ >+ case 461 : if (DEBUG) { System.out.println("ConditionalAndExpression ::= ConditionalAndExpression..."); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.AND_AND); >+ break; >+ >+ case 463 : if (DEBUG) { System.out.println("ConditionalOrExpression ::= ConditionalOrExpression..."); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.OR_OR); >+ break; >+ >+ case 465 : if (DEBUG) { System.out.println("ConditionalExpression ::= ConditionalOrExpression..."); } //$NON-NLS-1$ >+ consumeConditionalExpression(OperatorIds.QUESTIONCOLON) ; >+ break; >+ >+ case 468 : if (DEBUG) { System.out.println("Assignment ::= PostfixExpression AssignmentOperator..."); } //$NON-NLS-1$ >+ consumeAssignment(); >+ break; >+ >+ case 470 : if (DEBUG) { System.out.println("Assignment ::= InvalidArrayInitializerAssignement"); } //$NON-NLS-1$ >+ ignoreExpressionAssignment(); >+ break; >+ >+ case 471 : if (DEBUG) { System.out.println("AssignmentOperator ::= EQUAL"); } //$NON-NLS-1$ >+ consumeAssignmentOperator(EQUAL); >+ break; >+ >+ case 472 : if (DEBUG) { System.out.println("AssignmentOperator ::= MULTIPLY_EQUAL"); } //$NON-NLS-1$ >+ consumeAssignmentOperator(MULTIPLY); >+ break; >+ >+ case 473 : if (DEBUG) { System.out.println("AssignmentOperator ::= DIVIDE_EQUAL"); } //$NON-NLS-1$ >+ consumeAssignmentOperator(DIVIDE); >+ break; >+ >+ case 474 : if (DEBUG) { System.out.println("AssignmentOperator ::= REMAINDER_EQUAL"); } //$NON-NLS-1$ >+ consumeAssignmentOperator(REMAINDER); >+ break; >+ >+ case 475 : if (DEBUG) { System.out.println("AssignmentOperator ::= PLUS_EQUAL"); } //$NON-NLS-1$ >+ consumeAssignmentOperator(PLUS); >+ break; >+ >+ case 476 : if (DEBUG) { System.out.println("AssignmentOperator ::= MINUS_EQUAL"); } //$NON-NLS-1$ >+ consumeAssignmentOperator(MINUS); >+ break; >+ >+ case 477 : if (DEBUG) { System.out.println("AssignmentOperator ::= LEFT_SHIFT_EQUAL"); } //$NON-NLS-1$ >+ consumeAssignmentOperator(LEFT_SHIFT); >+ break; >+ >+ case 478 : if (DEBUG) { System.out.println("AssignmentOperator ::= RIGHT_SHIFT_EQUAL"); } //$NON-NLS-1$ >+ consumeAssignmentOperator(RIGHT_SHIFT); >+ break; >+ >+ case 479 : if (DEBUG) { System.out.println("AssignmentOperator ::= UNSIGNED_RIGHT_SHIFT_EQUAL"); } //$NON-NLS-1$ >+ consumeAssignmentOperator(UNSIGNED_RIGHT_SHIFT); >+ break; >+ >+ case 480 : if (DEBUG) { System.out.println("AssignmentOperator ::= AND_EQUAL"); } //$NON-NLS-1$ >+ consumeAssignmentOperator(AND); >+ break; >+ >+ case 481 : if (DEBUG) { System.out.println("AssignmentOperator ::= XOR_EQUAL"); } //$NON-NLS-1$ >+ consumeAssignmentOperator(XOR); >+ break; >+ >+ case 482 : if (DEBUG) { System.out.println("AssignmentOperator ::= OR_EQUAL"); } //$NON-NLS-1$ >+ consumeAssignmentOperator(OR); >+ break; >+ >+ case 486 : if (DEBUG) { System.out.println("Expressionopt ::="); } //$NON-NLS-1$ >+ consumeEmptyExpression(); >+ break; >+ >+ case 491 : if (DEBUG) { System.out.println("ClassBodyDeclarationsopt ::="); } //$NON-NLS-1$ >+ consumeEmptyClassBodyDeclarationsopt(); >+ break; >+ >+ case 492 : if (DEBUG) { System.out.println("ClassBodyDeclarationsopt ::= NestedType..."); } //$NON-NLS-1$ >+ consumeClassBodyDeclarationsopt(); >+ break; >+ >+ case 493 : if (DEBUG) { System.out.println("Modifiersopt ::="); } //$NON-NLS-1$ >+ consumeDefaultModifiers(); >+ break; >+ >+ case 494 : if (DEBUG) { System.out.println("Modifiersopt ::= Modifiers"); } //$NON-NLS-1$ >+ consumeModifiers(); >+ break; >+ >+ case 495 : if (DEBUG) { System.out.println("BlockStatementsopt ::="); } //$NON-NLS-1$ >+ consumeEmptyBlockStatementsopt(); >+ break; >+ >+ case 497 : if (DEBUG) { System.out.println("Dimsopt ::="); } //$NON-NLS-1$ >+ consumeEmptyDimsopt(); >+ break; >+ >+ case 499 : if (DEBUG) { System.out.println("ArgumentListopt ::="); } //$NON-NLS-1$ >+ consumeEmptyArgumentListopt(); >+ break; >+ >+ case 503 : if (DEBUG) { System.out.println("FormalParameterListopt ::="); } //$NON-NLS-1$ >+ consumeFormalParameterListopt(); >+ break; >+ >+ case 507 : if (DEBUG) { System.out.println("InterfaceMemberDeclarationsopt ::="); } //$NON-NLS-1$ >+ consumeEmptyInterfaceMemberDeclarationsopt(); >+ break; >+ >+ case 508 : if (DEBUG) { System.out.println("InterfaceMemberDeclarationsopt ::= NestedType..."); } //$NON-NLS-1$ >+ consumeInterfaceMemberDeclarationsopt(); >+ break; >+ >+ case 509 : if (DEBUG) { System.out.println("NestedType ::="); } //$NON-NLS-1$ >+ consumeNestedType(); >+ break; >+ >+ case 510 : if (DEBUG) { System.out.println("ForInitopt ::="); } //$NON-NLS-1$ >+ consumeEmptyForInitopt(); >+ break; >+ >+ case 512 : if (DEBUG) { System.out.println("ForUpdateopt ::="); } //$NON-NLS-1$ >+ consumeEmptyForUpdateopt(); >+ break; >+ >+ case 516 : if (DEBUG) { System.out.println("Catchesopt ::="); } //$NON-NLS-1$ >+ consumeEmptyCatchesopt(); >+ break; >+ >+ case 518 : if (DEBUG) { System.out.println("EnumDeclaration ::= EnumHeader EnumBody"); } //$NON-NLS-1$ >+ consumeEnumDeclaration(); >+ break; >+ >+ case 519 : if (DEBUG) { System.out.println("EnumHeader ::= EnumHeaderName ClassHeaderImplementsopt"); } //$NON-NLS-1$ >+ consumeEnumHeader(); >+ break; >+ >+ case 520 : if (DEBUG) { System.out.println("EnumHeaderName ::= Modifiersopt enum Identifier"); } //$NON-NLS-1$ >+ consumeEnumHeaderName(); >+ break; >+ >+ case 521 : if (DEBUG) { System.out.println("EnumHeaderName ::= Modifiersopt enum Identifier..."); } //$NON-NLS-1$ >+ consumeEnumHeaderNameWithTypeParameters(); >+ break; >+ >+ case 522 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumBodyDeclarationsopt RBRACE"); } //$NON-NLS-1$ >+ consumeEnumBodyNoConstants(); >+ break; >+ >+ case 523 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE COMMA EnumBodyDeclarationsopt..."); } //$NON-NLS-1$ >+ consumeEnumBodyNoConstants(); >+ break; >+ >+ case 524 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumConstants COMMA..."); } //$NON-NLS-1$ >+ consumeEnumBodyWithConstants(); >+ break; >+ >+ case 525 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumConstants..."); } //$NON-NLS-1$ >+ consumeEnumBodyWithConstants(); >+ break; >+ >+ case 527 : if (DEBUG) { System.out.println("EnumConstants ::= EnumConstants COMMA EnumConstant"); } //$NON-NLS-1$ >+ consumeEnumConstants(); >+ break; >+ >+ case 528 : if (DEBUG) { System.out.println("EnumConstantHeaderName ::= Modifiersopt Identifier"); } //$NON-NLS-1$ >+ consumeEnumConstantHeaderName(); >+ break; >+ >+ case 529 : if (DEBUG) { System.out.println("EnumConstantHeader ::= EnumConstantHeaderName..."); } //$NON-NLS-1$ >+ consumeEnumConstantHeader(); >+ break; >+ >+ case 530 : if (DEBUG) { System.out.println("EnumConstant ::= EnumConstantHeader ForceNoDiet..."); } //$NON-NLS-1$ >+ consumeEnumConstantWithClassBody(); >+ break; >+ >+ case 531 : if (DEBUG) { System.out.println("EnumConstant ::= EnumConstantHeader"); } //$NON-NLS-1$ >+ consumeEnumConstantNoClassBody(); >+ break; >+ >+ case 532 : if (DEBUG) { System.out.println("Arguments ::= LPAREN ArgumentListopt RPAREN"); } //$NON-NLS-1$ >+ consumeArguments(); >+ break; >+ >+ case 533 : if (DEBUG) { System.out.println("Argumentsopt ::="); } //$NON-NLS-1$ >+ consumeEmptyArguments(); >+ break; >+ >+ case 535 : if (DEBUG) { System.out.println("EnumDeclarations ::= SEMICOLON ClassBodyDeclarationsopt"); } //$NON-NLS-1$ >+ consumeEnumDeclarations(); >+ break; >+ >+ case 536 : if (DEBUG) { System.out.println("EnumBodyDeclarationsopt ::="); } //$NON-NLS-1$ >+ consumeEmptyEnumDeclarations(); >+ break; >+ >+ case 538 : if (DEBUG) { System.out.println("EnhancedForStatement ::= EnhancedForStatementHeader..."); } //$NON-NLS-1$ >+ consumeEnhancedForStatement(); >+ break; >+ >+ case 539 : if (DEBUG) { System.out.println("EnhancedForStatementNoShortIf ::=..."); } //$NON-NLS-1$ >+ consumeEnhancedForStatement(); >+ break; >+ >+ case 540 : if (DEBUG) { System.out.println("EnhancedForStatementHeaderInit ::= for LPAREN Type..."); } //$NON-NLS-1$ >+ consumeEnhancedForStatementHeaderInit(false); >+ break; >+ >+ case 541 : if (DEBUG) { System.out.println("EnhancedForStatementHeaderInit ::= for LPAREN Modifiers"); } //$NON-NLS-1$ >+ consumeEnhancedForStatementHeaderInit(true); >+ break; >+ >+ case 542 : if (DEBUG) { System.out.println("EnhancedForStatementHeader ::=..."); } //$NON-NLS-1$ >+ consumeEnhancedForStatementHeader(); >+ break; >+ >+ case 543 : if (DEBUG) { System.out.println("SingleStaticImportDeclaration ::=..."); } //$NON-NLS-1$ >+ consumeImportDeclaration(); >+ break; >+ >+ case 544 : if (DEBUG) { System.out.println("SingleStaticImportDeclarationName ::= import static Name"); } //$NON-NLS-1$ >+ consumeSingleStaticImportDeclarationName(); >+ break; >+ >+ case 545 : if (DEBUG) { System.out.println("StaticImportOnDemandDeclaration ::=..."); } //$NON-NLS-1$ >+ consumeImportDeclaration(); >+ break; >+ >+ case 546 : if (DEBUG) { System.out.println("StaticImportOnDemandDeclarationName ::= import static..."); } //$NON-NLS-1$ >+ consumeStaticImportOnDemandDeclarationName(); >+ break; >+ >+ case 547 : if (DEBUG) { System.out.println("TypeArguments ::= LESS TypeArgumentList1"); } //$NON-NLS-1$ >+ consumeTypeArguments(); >+ break; >+ >+ case 548 : if (DEBUG) { System.out.println("OnlyTypeArguments ::= LESS TypeArgumentList1"); } //$NON-NLS-1$ >+ consumeOnlyTypeArguments(); >+ break; >+ >+ case 550 : if (DEBUG) { System.out.println("TypeArgumentList1 ::= TypeArgumentList COMMA..."); } //$NON-NLS-1$ >+ consumeTypeArgumentList1(); >+ break; >+ >+ case 552 : if (DEBUG) { System.out.println("TypeArgumentList ::= TypeArgumentList COMMA TypeArgument"); } //$NON-NLS-1$ >+ consumeTypeArgumentList(); >+ break; >+ >+ case 553 : if (DEBUG) { System.out.println("TypeArgument ::= ReferenceType"); } //$NON-NLS-1$ >+ consumeTypeArgument(); >+ break; >+ >+ case 557 : if (DEBUG) { System.out.println("ReferenceType1 ::= ReferenceType GREATER"); } //$NON-NLS-1$ >+ consumeReferenceType1(); >+ break; >+ >+ case 558 : if (DEBUG) { System.out.println("ReferenceType1 ::= ClassOrInterface LESS..."); } //$NON-NLS-1$ >+ consumeTypeArgumentReferenceType1(); >+ break; >+ >+ case 560 : if (DEBUG) { System.out.println("TypeArgumentList2 ::= TypeArgumentList COMMA..."); } //$NON-NLS-1$ >+ consumeTypeArgumentList2(); >+ break; >+ >+ case 563 : if (DEBUG) { System.out.println("ReferenceType2 ::= ReferenceType RIGHT_SHIFT"); } //$NON-NLS-1$ >+ consumeReferenceType2(); >+ break; >+ >+ case 564 : if (DEBUG) { System.out.println("ReferenceType2 ::= ClassOrInterface LESS..."); } //$NON-NLS-1$ >+ consumeTypeArgumentReferenceType2(); >+ break; >+ >+ case 566 : if (DEBUG) { System.out.println("TypeArgumentList3 ::= TypeArgumentList COMMA..."); } //$NON-NLS-1$ >+ consumeTypeArgumentList3(); >+ break; >+ >+ case 569 : if (DEBUG) { System.out.println("ReferenceType3 ::= ReferenceType UNSIGNED_RIGHT_SHIFT"); } //$NON-NLS-1$ >+ consumeReferenceType3(); >+ break; >+ >+ case 570 : if (DEBUG) { System.out.println("Wildcard ::= QUESTION"); } //$NON-NLS-1$ >+ consumeWildcard(); >+ break; >+ >+ case 571 : if (DEBUG) { System.out.println("Wildcard ::= QUESTION WildcardBounds"); } //$NON-NLS-1$ >+ consumeWildcardWithBounds(); >+ break; >+ >+ case 572 : if (DEBUG) { System.out.println("WildcardBounds ::= extends ReferenceType"); } //$NON-NLS-1$ >+ consumeWildcardBoundsExtends(); >+ break; >+ >+ case 573 : if (DEBUG) { System.out.println("WildcardBounds ::= super ReferenceType"); } //$NON-NLS-1$ >+ consumeWildcardBoundsSuper(); >+ break; >+ >+ case 574 : if (DEBUG) { System.out.println("Wildcard1 ::= QUESTION GREATER"); } //$NON-NLS-1$ >+ consumeWildcard1(); >+ break; >+ >+ case 575 : if (DEBUG) { System.out.println("Wildcard1 ::= QUESTION WildcardBounds1"); } //$NON-NLS-1$ >+ consumeWildcard1WithBounds(); >+ break; >+ >+ case 576 : if (DEBUG) { System.out.println("WildcardBounds1 ::= extends ReferenceType1"); } //$NON-NLS-1$ >+ consumeWildcardBounds1Extends(); >+ break; >+ >+ case 577 : if (DEBUG) { System.out.println("WildcardBounds1 ::= super ReferenceType1"); } //$NON-NLS-1$ >+ consumeWildcardBounds1Super(); >+ break; >+ >+ case 578 : if (DEBUG) { System.out.println("Wildcard2 ::= QUESTION RIGHT_SHIFT"); } //$NON-NLS-1$ >+ consumeWildcard2(); >+ break; >+ >+ case 579 : if (DEBUG) { System.out.println("Wildcard2 ::= QUESTION WildcardBounds2"); } //$NON-NLS-1$ >+ consumeWildcard2WithBounds(); >+ break; >+ >+ case 580 : if (DEBUG) { System.out.println("WildcardBounds2 ::= extends ReferenceType2"); } //$NON-NLS-1$ >+ consumeWildcardBounds2Extends(); >+ break; >+ >+ case 581 : if (DEBUG) { System.out.println("WildcardBounds2 ::= super ReferenceType2"); } //$NON-NLS-1$ >+ consumeWildcardBounds2Super(); >+ break; >+ >+ case 582 : if (DEBUG) { System.out.println("Wildcard3 ::= QUESTION UNSIGNED_RIGHT_SHIFT"); } //$NON-NLS-1$ >+ consumeWildcard3(); >+ break; >+ >+ case 583 : if (DEBUG) { System.out.println("Wildcard3 ::= QUESTION WildcardBounds3"); } //$NON-NLS-1$ >+ consumeWildcard3WithBounds(); >+ break; >+ >+ case 584 : if (DEBUG) { System.out.println("WildcardBounds3 ::= extends ReferenceType3"); } //$NON-NLS-1$ >+ consumeWildcardBounds3Extends(); >+ break; >+ >+ case 585 : if (DEBUG) { System.out.println("WildcardBounds3 ::= super ReferenceType3"); } //$NON-NLS-1$ >+ consumeWildcardBounds3Super(); >+ break; >+ >+ case 586 : if (DEBUG) { System.out.println("TypeParameterHeader ::= Identifier"); } //$NON-NLS-1$ >+ consumeTypeParameterHeader(); >+ break; >+ >+ case 587 : if (DEBUG) { System.out.println("TypeParameters ::= LESS TypeParameterList1"); } //$NON-NLS-1$ >+ consumeTypeParameters(); >+ break; >+ >+ case 589 : if (DEBUG) { System.out.println("TypeParameterList ::= TypeParameterList COMMA..."); } //$NON-NLS-1$ >+ consumeTypeParameterList(); >+ break; >+ >+ case 591 : if (DEBUG) { System.out.println("TypeParameter ::= TypeParameterHeader extends..."); } //$NON-NLS-1$ >+ consumeTypeParameterWithExtends(); >+ break; >+ >+ case 592 : if (DEBUG) { System.out.println("TypeParameter ::= TypeParameterHeader extends..."); } //$NON-NLS-1$ >+ consumeTypeParameterWithExtendsAndBounds(); >+ break; >+ >+ case 594 : if (DEBUG) { System.out.println("AdditionalBoundList ::= AdditionalBoundList..."); } //$NON-NLS-1$ >+ consumeAdditionalBoundList(); >+ break; >+ >+ case 595 : if (DEBUG) { System.out.println("AdditionalBound ::= AND ReferenceType"); } //$NON-NLS-1$ >+ consumeAdditionalBound(); >+ break; >+ >+ case 597 : if (DEBUG) { System.out.println("TypeParameterList1 ::= TypeParameterList COMMA..."); } //$NON-NLS-1$ >+ consumeTypeParameterList1(); >+ break; >+ >+ case 598 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader GREATER"); } //$NON-NLS-1$ >+ consumeTypeParameter1(); >+ break; >+ >+ case 599 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader extends..."); } //$NON-NLS-1$ >+ consumeTypeParameter1WithExtends(); >+ break; >+ >+ case 600 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader extends..."); } //$NON-NLS-1$ >+ consumeTypeParameter1WithExtendsAndBounds(); >+ break; >+ >+ case 602 : if (DEBUG) { System.out.println("AdditionalBoundList1 ::= AdditionalBoundList..."); } //$NON-NLS-1$ >+ consumeAdditionalBoundList1(); >+ break; >+ >+ case 603 : if (DEBUG) { System.out.println("AdditionalBound1 ::= AND ReferenceType1"); } //$NON-NLS-1$ >+ consumeAdditionalBound1(); >+ break; >+ >+ case 609 : if (DEBUG) { System.out.println("UnaryExpression_NotName ::= PLUS PushPosition..."); } //$NON-NLS-1$ >+ consumeUnaryExpression(OperatorIds.PLUS); >+ break; >+ >+ case 610 : if (DEBUG) { System.out.println("UnaryExpression_NotName ::= MINUS PushPosition..."); } //$NON-NLS-1$ >+ consumeUnaryExpression(OperatorIds.MINUS); >+ break; >+ >+ case 613 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus_NotName ::= TWIDDLE..."); } //$NON-NLS-1$ >+ consumeUnaryExpression(OperatorIds.TWIDDLE); >+ break; >+ >+ case 614 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus_NotName ::= NOT PushPosition"); } //$NON-NLS-1$ >+ consumeUnaryExpression(OperatorIds.NOT); >+ break; >+ >+ case 617 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.MULTIPLY); >+ break; >+ >+ case 618 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name MULTIPLY..."); } //$NON-NLS-1$ >+ consumeBinaryExpressionWithName(OperatorIds.MULTIPLY); >+ break; >+ >+ case 619 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.DIVIDE); >+ break; >+ >+ case 620 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name DIVIDE..."); } //$NON-NLS-1$ >+ consumeBinaryExpressionWithName(OperatorIds.DIVIDE); >+ break; >+ >+ case 621 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.REMAINDER); >+ break; >+ >+ case 622 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name REMAINDER..."); } //$NON-NLS-1$ >+ consumeBinaryExpressionWithName(OperatorIds.REMAINDER); >+ break; >+ >+ case 624 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::=..."); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.PLUS); >+ break; >+ >+ case 625 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::= Name PLUS..."); } //$NON-NLS-1$ >+ consumeBinaryExpressionWithName(OperatorIds.PLUS); >+ break; >+ >+ case 626 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::=..."); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.MINUS); >+ break; >+ >+ case 627 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::= Name MINUS..."); } //$NON-NLS-1$ >+ consumeBinaryExpressionWithName(OperatorIds.MINUS); >+ break; >+ >+ case 629 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.LEFT_SHIFT); >+ break; >+ >+ case 630 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name LEFT_SHIFT..."); } //$NON-NLS-1$ >+ consumeBinaryExpressionWithName(OperatorIds.LEFT_SHIFT); >+ break; >+ >+ case 631 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.RIGHT_SHIFT); >+ break; >+ >+ case 632 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name RIGHT_SHIFT..."); } //$NON-NLS-1$ >+ consumeBinaryExpressionWithName(OperatorIds.RIGHT_SHIFT); >+ break; >+ >+ case 633 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.UNSIGNED_RIGHT_SHIFT); >+ break; >+ >+ case 634 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name UNSIGNED_RIGHT_SHIFT..."); } //$NON-NLS-1$ >+ consumeBinaryExpressionWithName(OperatorIds.UNSIGNED_RIGHT_SHIFT); >+ break; >+ >+ case 636 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= ShiftExpression_NotName"); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.LESS); >+ break; >+ >+ case 637 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name LESS..."); } //$NON-NLS-1$ >+ consumeBinaryExpressionWithName(OperatorIds.LESS); >+ break; >+ >+ case 638 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= ShiftExpression_NotName"); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.GREATER); >+ break; >+ >+ case 639 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name GREATER..."); } //$NON-NLS-1$ >+ consumeBinaryExpressionWithName(OperatorIds.GREATER); >+ break; >+ >+ case 640 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::=..."); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.LESS_EQUAL); >+ break; >+ >+ case 641 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name LESS_EQUAL..."); } //$NON-NLS-1$ >+ consumeBinaryExpressionWithName(OperatorIds.LESS_EQUAL); >+ break; >+ >+ case 642 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::=..."); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.GREATER_EQUAL); >+ break; >+ >+ case 643 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name GREATER_EQUAL..."); } //$NON-NLS-1$ >+ consumeBinaryExpressionWithName(OperatorIds.GREATER_EQUAL); >+ break; >+ >+ case 645 : if (DEBUG) { System.out.println("InstanceofExpression_NotName ::= Name instanceof..."); } //$NON-NLS-1$ >+ consumeInstanceOfExpressionWithName(); >+ break; >+ >+ case 646 : if (DEBUG) { System.out.println("InstanceofExpression_NotName ::=..."); } //$NON-NLS-1$ >+ consumeInstanceOfExpression(); >+ break; >+ >+ case 648 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::=..."); } //$NON-NLS-1$ >+ consumeEqualityExpression(OperatorIds.EQUAL_EQUAL); >+ break; >+ >+ case 649 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::= Name EQUAL_EQUAL..."); } //$NON-NLS-1$ >+ consumeEqualityExpressionWithName(OperatorIds.EQUAL_EQUAL); >+ break; >+ >+ case 650 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::=..."); } //$NON-NLS-1$ >+ consumeEqualityExpression(OperatorIds.NOT_EQUAL); >+ break; >+ >+ case 651 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::= Name NOT_EQUAL..."); } //$NON-NLS-1$ >+ consumeEqualityExpressionWithName(OperatorIds.NOT_EQUAL); >+ break; >+ >+ case 653 : if (DEBUG) { System.out.println("AndExpression_NotName ::= AndExpression_NotName AND..."); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.AND); >+ break; >+ >+ case 654 : if (DEBUG) { System.out.println("AndExpression_NotName ::= Name AND EqualityExpression"); } //$NON-NLS-1$ >+ consumeBinaryExpressionWithName(OperatorIds.AND); >+ break; >+ >+ case 656 : if (DEBUG) { System.out.println("ExclusiveOrExpression_NotName ::=..."); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.XOR); >+ break; >+ >+ case 657 : if (DEBUG) { System.out.println("ExclusiveOrExpression_NotName ::= Name XOR AndExpression"); } //$NON-NLS-1$ >+ consumeBinaryExpressionWithName(OperatorIds.XOR); >+ break; >+ >+ case 659 : if (DEBUG) { System.out.println("InclusiveOrExpression_NotName ::=..."); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.OR); >+ break; >+ >+ case 660 : if (DEBUG) { System.out.println("InclusiveOrExpression_NotName ::= Name OR..."); } //$NON-NLS-1$ >+ consumeBinaryExpressionWithName(OperatorIds.OR); >+ break; >+ >+ case 662 : if (DEBUG) { System.out.println("ConditionalAndExpression_NotName ::=..."); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.AND_AND); >+ break; >+ >+ case 663 : if (DEBUG) { System.out.println("ConditionalAndExpression_NotName ::= Name AND_AND..."); } //$NON-NLS-1$ >+ consumeBinaryExpressionWithName(OperatorIds.AND_AND); >+ break; >+ >+ case 665 : if (DEBUG) { System.out.println("ConditionalOrExpression_NotName ::=..."); } //$NON-NLS-1$ >+ consumeBinaryExpression(OperatorIds.OR_OR); >+ break; >+ >+ case 666 : if (DEBUG) { System.out.println("ConditionalOrExpression_NotName ::= Name OR_OR..."); } //$NON-NLS-1$ >+ consumeBinaryExpressionWithName(OperatorIds.OR_OR); >+ break; >+ >+ case 668 : if (DEBUG) { System.out.println("ConditionalExpression_NotName ::=..."); } //$NON-NLS-1$ >+ consumeConditionalExpression(OperatorIds.QUESTIONCOLON) ; >+ break; >+ >+ case 669 : if (DEBUG) { System.out.println("ConditionalExpression_NotName ::= Name QUESTION..."); } //$NON-NLS-1$ >+ consumeConditionalExpressionWithName(OperatorIds.QUESTIONCOLON) ; >+ break; >+ >+ case 673 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= Modifiers AT..."); } //$NON-NLS-1$ >+ consumeAnnotationTypeDeclarationHeaderName() ; >+ break; >+ >+ case 674 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= Modifiers AT..."); } //$NON-NLS-1$ >+ consumeAnnotationTypeDeclarationHeaderNameWithTypeParameters() ; >+ break; >+ >+ case 675 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= AT..."); } //$NON-NLS-1$ >+ consumeAnnotationTypeDeclarationHeaderNameWithTypeParameters() ; >+ break; >+ >+ case 676 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= AT..."); } //$NON-NLS-1$ >+ consumeAnnotationTypeDeclarationHeaderName() ; >+ break; >+ >+ case 677 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeader ::=..."); } //$NON-NLS-1$ >+ consumeAnnotationTypeDeclarationHeader() ; >+ break; >+ >+ case 678 : if (DEBUG) { System.out.println("AnnotationTypeDeclaration ::=..."); } //$NON-NLS-1$ >+ consumeAnnotationTypeDeclaration() ; >+ break; >+ >+ case 680 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarationsopt ::="); } //$NON-NLS-1$ >+ consumeEmptyAnnotationTypeMemberDeclarationsopt() ; >+ break; >+ >+ case 681 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarationsopt ::= NestedType..."); } //$NON-NLS-1$ >+ consumeAnnotationTypeMemberDeclarationsopt() ; >+ break; >+ >+ case 683 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarations ::=..."); } //$NON-NLS-1$ >+ consumeAnnotationTypeMemberDeclarations() ; >+ break; >+ >+ case 684 : if (DEBUG) { System.out.println("AnnotationMethodHeaderName ::= Modifiersopt..."); } //$NON-NLS-1$ >+ consumeMethodHeaderNameWithTypeParameters(true); >+ break; >+ >+ case 685 : if (DEBUG) { System.out.println("AnnotationMethodHeaderName ::= Modifiersopt Type..."); } //$NON-NLS-1$ >+ consumeMethodHeaderName(true); >+ break; >+ >+ case 686 : if (DEBUG) { System.out.println("AnnotationMethodHeaderDefaultValueopt ::="); } //$NON-NLS-1$ >+ consumeEmptyMethodHeaderDefaultValue() ; >+ break; >+ >+ case 687 : if (DEBUG) { System.out.println("AnnotationMethodHeaderDefaultValueopt ::= DefaultValue"); } //$NON-NLS-1$ >+ consumeMethodHeaderDefaultValue(); >+ break; >+ >+ case 688 : if (DEBUG) { System.out.println("AnnotationMethodHeader ::= AnnotationMethodHeaderName..."); } //$NON-NLS-1$ >+ consumeMethodHeader(); >+ break; >+ >+ case 689 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclaration ::=..."); } //$NON-NLS-1$ >+ consumeAnnotationTypeMemberDeclaration() ; >+ break; >+ >+ case 697 : if (DEBUG) { System.out.println("AnnotationName ::= AT Name"); } //$NON-NLS-1$ >+ consumeAnnotationName() ; >+ break; >+ >+ case 698 : if (DEBUG) { System.out.println("NormalAnnotation ::= AnnotationName LPAREN..."); } //$NON-NLS-1$ >+ consumeNormalAnnotation() ; >+ break; >+ >+ case 699 : if (DEBUG) { System.out.println("MemberValuePairsopt ::="); } //$NON-NLS-1$ >+ consumeEmptyMemberValuePairsopt() ; >+ break; >+ >+ case 702 : if (DEBUG) { System.out.println("MemberValuePairs ::= MemberValuePairs COMMA..."); } //$NON-NLS-1$ >+ consumeMemberValuePairs() ; >+ break; >+ >+ case 703 : if (DEBUG) { System.out.println("MemberValuePair ::= SimpleName EQUAL EnterMemberValue..."); } //$NON-NLS-1$ >+ consumeMemberValuePair() ; >+ break; >+ >+ case 704 : if (DEBUG) { System.out.println("EnterMemberValue ::="); } //$NON-NLS-1$ >+ consumeEnterMemberValue() ; >+ break; >+ >+ case 705 : if (DEBUG) { System.out.println("ExitMemberValue ::="); } //$NON-NLS-1$ >+ consumeExitMemberValue() ; >+ break; >+ >+ case 707 : if (DEBUG) { System.out.println("MemberValue ::= Name"); } //$NON-NLS-1$ >+ consumeMemberValueAsName() ; >+ break; >+ >+ case 710 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); } //$NON-NLS-1$ >+ consumeMemberValueArrayInitializer() ; >+ break; >+ >+ case 711 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); } //$NON-NLS-1$ >+ consumeMemberValueArrayInitializer() ; >+ break; >+ >+ case 712 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); } //$NON-NLS-1$ >+ consumeEmptyMemberValueArrayInitializer() ; >+ break; >+ >+ case 713 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); } //$NON-NLS-1$ >+ consumeEmptyMemberValueArrayInitializer() ; >+ break; >+ >+ case 714 : if (DEBUG) { System.out.println("EnterMemberValueArrayInitializer ::="); } //$NON-NLS-1$ >+ consumeEnterMemberValueArrayInitializer() ; >+ break; >+ >+ case 716 : if (DEBUG) { System.out.println("MemberValues ::= MemberValues COMMA MemberValue"); } //$NON-NLS-1$ >+ consumeMemberValues() ; >+ break; >+ >+ case 717 : if (DEBUG) { System.out.println("MarkerAnnotation ::= AnnotationName"); } //$NON-NLS-1$ >+ consumeMarkerAnnotation() ; >+ break; >+ >+ case 718 : if (DEBUG) { System.out.println("SingleMemberAnnotationMemberValue ::= MemberValue"); } //$NON-NLS-1$ >+ consumeSingleMemberAnnotationMemberValue() ; >+ break; >+ >+ case 719 : if (DEBUG) { System.out.println("SingleMemberAnnotation ::= AnnotationName LPAREN..."); } //$NON-NLS-1$ >+ consumeSingleMemberAnnotation() ; >+ break; >+ >+ case 720 : if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= Modifiersopt TypeParameters"); } //$NON-NLS-1$ >+ consumeRecoveryMethodHeaderNameWithTypeParameters(); >+ break; >+ >+ case 721 : if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= Modifiersopt Type..."); } //$NON-NLS-1$ >+ consumeRecoveryMethodHeaderName(); >+ break; >+ >+ case 722 : if (DEBUG) { System.out.println("RecoveryMethodHeader ::= RecoveryMethodHeaderName..."); } //$NON-NLS-1$ >+ consumeMethodHeader(); >+ break; >+ >+ case 723 : if (DEBUG) { System.out.println("RecoveryMethodHeader ::= RecoveryMethodHeaderName..."); } //$NON-NLS-1$ >+ consumeMethodHeader(); >+ break; >+ >+ } >+} >+protected void consumeEnterInstanceCreationArgumentList() { >+ this.shouldDeferRecovery = true; > } > protected void consumeSimpleAssertStatement() { > // AssertStatement ::= 'assert' Expression ';' >@@ -8852,11 +8866,11 @@ > int c1, c2, c3, c4; > index[0]++; > while (comment[index[0]] == 'u') index[0]++; >- if (!(((c1 = ScannerHelper.getNumericValue(comment[index[0]++])) > 15 >+ if (!(((c1 = ScannerHelper.getHexadecimalValue(comment[index[0]++])) > 15 > || c1 < 0) >- || ((c2 = ScannerHelper.getNumericValue(comment[index[0]++])) > 15 || c2 < 0) >- || ((c3 = ScannerHelper.getNumericValue(comment[index[0]++])) > 15 || c3 < 0) >- || ((c4 = ScannerHelper.getNumericValue(comment[index[0]++])) > 15 || c4 < 0))) { >+ || ((c2 = ScannerHelper.getHexadecimalValue(comment[index[0]++])) > 15 || c2 < 0) >+ || ((c3 = ScannerHelper.getHexadecimalValue(comment[index[0]++])) > 15 || c3 < 0) >+ || ((c4 = ScannerHelper.getHexadecimalValue(comment[index[0]++])) > 15 || c4 < 0))) { > nextCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4); > } > break; >@@ -9551,8 +9565,8 @@ > this.stack[this.stateStackTop] = act; > > act = tAction(act, this.currentToken); >- if (act == ERROR_ACTION || this.restartRecovery) { >- >+ if (act == ERROR_ACTION || (this.restartRecovery && !this.shouldDeferRecovery)) { >+ this.shouldDeferRecovery = false; > if (DEBUG_AUTOMATON) { > if (this.restartRecovery) { > System.out.println("Restart - "); //$NON-NLS-1$ >@@ -9722,6 +9736,8 @@ > boolean oldMethodRecoveryActivated = this.methodRecoveryActivated; > if(this.options.performMethodsFullRecovery) { > this.methodRecoveryActivated = true; >+ // we should not relocate bodyStart if there is a block within the statements >+ this.ignoreNextOpeningBrace = true; > } > > initialize(); >@@ -9971,6 +9987,8 @@ > > boolean oldMethodRecoveryActivated = this.methodRecoveryActivated; > if(this.options.performMethodsFullRecovery) { >+ // we should not relocate bodyStart if there is a block within the statements >+ this.ignoreNextOpeningBrace = true; > this.methodRecoveryActivated = true; > this.rParenPos = md.sourceEnd; > } >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java >index 3c5c2b6..273425d 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java >@@ -1,35 +1,35 @@ >-/******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation 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: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.jdt.internal.compiler.parser; >- >-/*An interface that contains static declarations for some basic information >- about the parser such as the number of rules in the grammar, the starting state, etc...*/ >-public interface ParserBasicInformation { >- >- int ERROR_SYMBOL = 110, >- MAX_NAME_LENGTH = 41, >- NUM_STATES = 1002, >- >- NT_OFFSET = 110, >- SCOPE_UBOUND = 137, >- SCOPE_SIZE = 138, >- LA_STATE_OFFSET = 12446, >- MAX_LA = 1, >- NUM_RULES = 722, >- NUM_TERMINALS = 110, >- NUM_NON_TERMINALS = 323, >- NUM_SYMBOLS = 433, >- START_STATE = 1084, >- EOFT_SYMBOL = 69, >- EOLT_SYMBOL = 69, >- ACCEPT_ACTION = 12445, >- ERROR_ACTION = 12446; >-} >+/******************************************************************************* >+ * Copyright (c) 2000, 2011 IBM Corporation 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.internal.compiler.parser; >+ >+/*An interface that contains static declarations for some basic information >+ about the parser such as the number of rules in the grammar, the starting state, etc...*/ >+public interface ParserBasicInformation { >+ >+ int ERROR_SYMBOL = 110, >+ MAX_NAME_LENGTH = 41, >+ NUM_STATES = 1008, >+ >+ NT_OFFSET = 110, >+ SCOPE_UBOUND = 137, >+ SCOPE_SIZE = 138, >+ LA_STATE_OFFSET = 12379, >+ MAX_LA = 1, >+ NUM_RULES = 723, >+ NUM_TERMINALS = 110, >+ NUM_NON_TERMINALS = 324, >+ NUM_SYMBOLS = 434, >+ START_STATE = 1260, >+ EOFT_SYMBOL = 69, >+ EOLT_SYMBOL = 69, >+ ACCEPT_ACTION = 12378, >+ ERROR_ACTION = 12379; >+} >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredElement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredElement.java >index 7fd5327..81612f5 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredElement.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredElement.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2008 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -107,6 +107,15 @@ > /* default behavior is to delegate recording to parent if any */ > resetPendingModifiers(); > if (this.parent == null) return this; // ignore >+ if (this instanceof RecoveredType) { >+ TypeDeclaration typeDeclaration = ((RecoveredType) this).typeDeclaration; >+ if (typeDeclaration != null && (typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) { >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=291040, new X(<SelectOnMessageSend:zoo()>) { ??? >+ if (statement.sourceStart > typeDeclaration.sourceStart && statement.sourceEnd < typeDeclaration.sourceEnd) { >+ return this; >+ } >+ } >+ } > this.updateSourceEndIfNecessary(previousAvailableLineEnd(statement.sourceStart - 1)); > return this.parent.add(statement, bracketBalanceValue); > } >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredType.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredType.java >index ea53456..aac6d22 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredType.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredType.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contribution for Bug 366003 - CCE in ASTNode.resolveAnnotations(ASTNode.java:639) > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.parser; > >@@ -773,4 +774,23 @@ > this.typeDeclaration.bodyEnd = end; > } > } >+public void annotationsConsumed(Annotation[] consumedAnnotations) { >+ RecoveredAnnotation[] keep = new RecoveredAnnotation[this.pendingAnnotationCount]; >+ int numKeep = 0; >+ int pendingCount = this.pendingAnnotationCount; >+ int consumedLength = consumedAnnotations.length; >+ outerLoop: >+ for (int i = 0; i < pendingCount; i++) { >+ Annotation pendingAnnotationAST = this.pendingAnnotations[i].annotation; >+ for (int j = 0; j < consumedLength; j++) { >+ if (consumedAnnotations[j] == pendingAnnotationAST) >+ continue outerLoop; >+ } >+ keep[numKeep++] = this.pendingAnnotations[i]; >+ } >+ if (numKeep != this.pendingAnnotationCount) { >+ this.pendingAnnotations = keep; >+ this.pendingAnnotationCount = numKeep; >+ } >+} > } >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java >index d152a23..b381b01 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contribution for bug 186342 - [compiler][null] Using annotations for null checking > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.parser; > >@@ -1819,13 +1820,13 @@ > this.currentPosition += (this.eofPosition - this.currentPosition); > throw new InvalidInputException(INVALID_UNICODE_ESCAPE); > } >- if ((c1 = ScannerHelper.getNumericValue(this.source[this.currentPosition++])) > 15 >+ if ((c1 = ScannerHelper.getHexadecimalValue(this.source[this.currentPosition++])) > 15 > || c1 < 0 >- || (c2 = ScannerHelper.getNumericValue(this.source[this.currentPosition++])) > 15 >+ || (c2 = ScannerHelper.getHexadecimalValue(this.source[this.currentPosition++])) > 15 > || c2 < 0 >- || (c3 = ScannerHelper.getNumericValue(this.source[this.currentPosition++])) > 15 >+ || (c3 = ScannerHelper.getHexadecimalValue(this.source[this.currentPosition++])) > 15 > || c3 < 0 >- || (c4 = ScannerHelper.getNumericValue(this.source[this.currentPosition++])) > 15 >+ || (c4 = ScannerHelper.getHexadecimalValue(this.source[this.currentPosition++])) > 15 > || c4 < 0){ > throw new InvalidInputException(INVALID_UNICODE_ESCAPE); > } >@@ -2725,18 +2726,18 @@ > // OctalDigit OctalDigit > // ZeroToThree OctalDigit OctalDigit > >- int number = ScannerHelper.getNumericValue(this.currentCharacter); >+ int number = ScannerHelper.getHexadecimalValue(this.currentCharacter); > if (number >= 0 && number <= 7) { > boolean zeroToThreeNot = number > 3; > if (ScannerHelper.isDigit(this.currentCharacter = this.source[this.currentPosition++])) { >- int digit = ScannerHelper.getNumericValue(this.currentCharacter); >+ int digit = ScannerHelper.getHexadecimalValue(this.currentCharacter); > if (digit >= 0 && digit <= 7) { > number = (number * 8) + digit; > if (ScannerHelper.isDigit(this.currentCharacter = this.source[this.currentPosition++])) { > if (zeroToThreeNot) {// has read \NotZeroToThree OctalDigit Digit --> ignore last character > this.currentPosition--; > } else { >- digit = ScannerHelper.getNumericValue(this.currentCharacter); >+ digit = ScannerHelper.getHexadecimalValue(this.currentCharacter); > if (digit >= 0 && digit <= 7){ // has read \ZeroToThree OctalDigit OctalDigit > number = (number * 8) + digit; > } else {// has read \ZeroToThree OctalDigit NonOctalDigit --> ignore last character >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ScannerHelper.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ScannerHelper.java >index 69c1107..4ee486e 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ScannerHelper.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ScannerHelper.java >@@ -475,6 +475,50 @@ > } > return Character.getNumericValue(c); > } >+public static int getHexadecimalValue(char c) { >+ switch(c) { >+ case '0' : >+ return 0; >+ case '1' : >+ return 1; >+ case '2' : >+ return 2; >+ case '3' : >+ return 3; >+ case '4' : >+ return 4; >+ case '5' : >+ return 5; >+ case '6' : >+ return 6; >+ case '7' : >+ return 7; >+ case '8' : >+ return 8; >+ case '9' : >+ return 9; >+ case 'A' : >+ case 'a' : >+ return 10; >+ case 'B' : >+ case 'b' : >+ return 11; >+ case 'C' : >+ case 'c' : >+ return 12; >+ case 'D' : >+ case 'd' : >+ return 13; >+ case 'E' : >+ case 'e' : >+ return 14; >+ case 'F' : >+ case 'f' : >+ return 15; >+ default: >+ return -1; >+ } >+} > public static char toUpperCase(char c) { > if (c < MAX_OBVIOUS) { > if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_UPPER_LETTER) != 0) { >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java >index bda4da2..e1406d0 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java >@@ -1,146 +1,146 @@ >-/******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation 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: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.jdt.internal.compiler.parser; >- >-/** >- * IMPORTANT NOTE: These constants are dedicated to the internal Scanner implementation. >- * It is mirrored in org.eclipse.jdt.core.compiler public package where it is API. >- * The mirror implementation is using the backward compatible ITerminalSymbols constant >- * definitions (stable with 2.0), whereas the internal implementation uses TerminalTokens >- * which constant values reflect the latest parser generation state. >- */ >-/** >- * Maps each terminal symbol in the java-grammar into a unique integer. >- * This integer is used to represent the terminal when computing a parsing action. >- * >- * Disclaimer : These constant values are generated automatically using a Java >- * grammar, therefore their actual values are subject to change if new keywords >- * were added to the language (for instance, 'assert' is a keyword in 1.4). >- */ >-public interface TerminalTokens { >- >- // special tokens not part of grammar - not autogenerated >- int TokenNameWHITESPACE = 1000, >- TokenNameCOMMENT_LINE = 1001, >- TokenNameCOMMENT_BLOCK = 1002, >- TokenNameCOMMENT_JAVADOC = 1003; >- >- int TokenNameIdentifier = 26, >- TokenNameabstract = 56, >- TokenNameassert = 74, >- TokenNameboolean = 32, >- TokenNamebreak = 75, >- TokenNamebyte = 33, >- TokenNamecase = 102, >- TokenNamecatch = 100, >- TokenNamechar = 34, >- TokenNameclass = 72, >- TokenNamecontinue = 76, >- TokenNameconst = 108, >- TokenNamedefault = 97, >- TokenNamedo = 77, >- TokenNamedouble = 35, >- TokenNameelse = 104, >- TokenNameenum = 98, >- TokenNameextends = 99, >- TokenNamefalse = 44, >- TokenNamefinal = 57, >- TokenNamefinally = 103, >- TokenNamefloat = 36, >- TokenNamefor = 78, >- TokenNamegoto = 109, >- TokenNameif = 79, >- TokenNameimplements = 106, >- TokenNameimport = 101, >- TokenNameinstanceof = 13, >- TokenNameint = 37, >- TokenNameinterface = 95, >- TokenNamelong = 38, >- TokenNamenative = 58, >- TokenNamenew = 43, >- TokenNamenull = 45, >- TokenNamepackage = 96, >- TokenNameprivate = 59, >- TokenNameprotected = 60, >- TokenNamepublic = 61, >- TokenNamereturn = 80, >- TokenNameshort = 39, >- TokenNamestatic = 54, >- TokenNamestrictfp = 62, >- TokenNamesuper = 41, >- TokenNameswitch = 81, >- TokenNamesynchronized = 55, >- TokenNamethis = 42, >- TokenNamethrow = 82, >- TokenNamethrows = 105, >- TokenNametransient = 63, >- TokenNametrue = 46, >- TokenNametry = 83, >- TokenNamevoid = 40, >- TokenNamevolatile = 64, >- TokenNamewhile = 73, >- TokenNameIntegerLiteral = 47, >- TokenNameLongLiteral = 48, >- TokenNameFloatingPointLiteral = 49, >- TokenNameDoubleLiteral = 50, >- TokenNameCharacterLiteral = 51, >- TokenNameStringLiteral = 52, >- TokenNamePLUS_PLUS = 8, >- TokenNameMINUS_MINUS = 9, >- TokenNameEQUAL_EQUAL = 18, >- TokenNameLESS_EQUAL = 14, >- TokenNameGREATER_EQUAL = 15, >- TokenNameNOT_EQUAL = 19, >- TokenNameLEFT_SHIFT = 17, >- TokenNameRIGHT_SHIFT = 10, >- TokenNameUNSIGNED_RIGHT_SHIFT = 12, >- TokenNamePLUS_EQUAL = 84, >- TokenNameMINUS_EQUAL = 85, >- TokenNameMULTIPLY_EQUAL = 86, >- TokenNameDIVIDE_EQUAL = 87, >- TokenNameAND_EQUAL = 88, >- TokenNameOR_EQUAL = 89, >- TokenNameXOR_EQUAL = 90, >- TokenNameREMAINDER_EQUAL = 91, >- TokenNameLEFT_SHIFT_EQUAL = 92, >- TokenNameRIGHT_SHIFT_EQUAL = 93, >- TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL = 94, >- TokenNameOR_OR = 25, >- TokenNameAND_AND = 24, >- TokenNamePLUS = 1, >- TokenNameMINUS = 2, >- TokenNameNOT = 66, >- TokenNameREMAINDER = 5, >- TokenNameXOR = 21, >- TokenNameAND = 20, >- TokenNameMULTIPLY = 4, >- TokenNameOR = 22, >- TokenNameTWIDDLE = 67, >- TokenNameDIVIDE = 6, >- TokenNameGREATER = 11, >- TokenNameLESS = 7, >- TokenNameLPAREN = 29, >- TokenNameRPAREN = 28, >- TokenNameLBRACE = 68, >- TokenNameRBRACE = 31, >- TokenNameLBRACKET = 16, >- TokenNameRBRACKET = 70, >- TokenNameSEMICOLON = 27, >- TokenNameQUESTION = 23, >- TokenNameCOLON = 65, >- TokenNameCOMMA = 30, >- TokenNameDOT = 3, >- TokenNameEQUAL = 71, >- TokenNameAT = 53, >- TokenNameELLIPSIS = 107, >- TokenNameEOF = 69, >- TokenNameERROR = 110; >-} >+/******************************************************************************* >+ * Copyright (c) 2000, 2011 IBM Corporation 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.internal.compiler.parser; >+ >+/** >+ * IMPORTANT NOTE: These constants are dedicated to the internal Scanner implementation. >+ * It is mirrored in org.eclipse.jdt.core.compiler public package where it is API. >+ * The mirror implementation is using the backward compatible ITerminalSymbols constant >+ * definitions (stable with 2.0), whereas the internal implementation uses TerminalTokens >+ * which constant values reflect the latest parser generation state. >+ */ >+/** >+ * Maps each terminal symbol in the java-grammar into a unique integer. >+ * This integer is used to represent the terminal when computing a parsing action. >+ * >+ * Disclaimer : These constant values are generated automatically using a Java >+ * grammar, therefore their actual values are subject to change if new keywords >+ * were added to the language (for instance, 'assert' is a keyword in 1.4). >+ */ >+public interface TerminalTokens { >+ >+ // special tokens not part of grammar - not autogenerated >+ int TokenNameWHITESPACE = 1000, >+ TokenNameCOMMENT_LINE = 1001, >+ TokenNameCOMMENT_BLOCK = 1002, >+ TokenNameCOMMENT_JAVADOC = 1003; >+ >+ int TokenNameIdentifier = 26, >+ TokenNameabstract = 56, >+ TokenNameassert = 74, >+ TokenNameboolean = 32, >+ TokenNamebreak = 75, >+ TokenNamebyte = 33, >+ TokenNamecase = 102, >+ TokenNamecatch = 100, >+ TokenNamechar = 34, >+ TokenNameclass = 72, >+ TokenNamecontinue = 76, >+ TokenNameconst = 108, >+ TokenNamedefault = 97, >+ TokenNamedo = 77, >+ TokenNamedouble = 35, >+ TokenNameelse = 104, >+ TokenNameenum = 98, >+ TokenNameextends = 99, >+ TokenNamefalse = 44, >+ TokenNamefinal = 57, >+ TokenNamefinally = 103, >+ TokenNamefloat = 36, >+ TokenNamefor = 78, >+ TokenNamegoto = 109, >+ TokenNameif = 79, >+ TokenNameimplements = 106, >+ TokenNameimport = 101, >+ TokenNameinstanceof = 13, >+ TokenNameint = 37, >+ TokenNameinterface = 95, >+ TokenNamelong = 38, >+ TokenNamenative = 58, >+ TokenNamenew = 43, >+ TokenNamenull = 45, >+ TokenNamepackage = 96, >+ TokenNameprivate = 59, >+ TokenNameprotected = 60, >+ TokenNamepublic = 61, >+ TokenNamereturn = 80, >+ TokenNameshort = 39, >+ TokenNamestatic = 54, >+ TokenNamestrictfp = 62, >+ TokenNamesuper = 41, >+ TokenNameswitch = 81, >+ TokenNamesynchronized = 55, >+ TokenNamethis = 42, >+ TokenNamethrow = 82, >+ TokenNamethrows = 105, >+ TokenNametransient = 63, >+ TokenNametrue = 46, >+ TokenNametry = 83, >+ TokenNamevoid = 40, >+ TokenNamevolatile = 64, >+ TokenNamewhile = 73, >+ TokenNameIntegerLiteral = 47, >+ TokenNameLongLiteral = 48, >+ TokenNameFloatingPointLiteral = 49, >+ TokenNameDoubleLiteral = 50, >+ TokenNameCharacterLiteral = 51, >+ TokenNameStringLiteral = 52, >+ TokenNamePLUS_PLUS = 8, >+ TokenNameMINUS_MINUS = 9, >+ TokenNameEQUAL_EQUAL = 18, >+ TokenNameLESS_EQUAL = 14, >+ TokenNameGREATER_EQUAL = 15, >+ TokenNameNOT_EQUAL = 19, >+ TokenNameLEFT_SHIFT = 17, >+ TokenNameRIGHT_SHIFT = 10, >+ TokenNameUNSIGNED_RIGHT_SHIFT = 12, >+ TokenNamePLUS_EQUAL = 84, >+ TokenNameMINUS_EQUAL = 85, >+ TokenNameMULTIPLY_EQUAL = 86, >+ TokenNameDIVIDE_EQUAL = 87, >+ TokenNameAND_EQUAL = 88, >+ TokenNameOR_EQUAL = 89, >+ TokenNameXOR_EQUAL = 90, >+ TokenNameREMAINDER_EQUAL = 91, >+ TokenNameLEFT_SHIFT_EQUAL = 92, >+ TokenNameRIGHT_SHIFT_EQUAL = 93, >+ TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL = 94, >+ TokenNameOR_OR = 25, >+ TokenNameAND_AND = 24, >+ TokenNamePLUS = 1, >+ TokenNameMINUS = 2, >+ TokenNameNOT = 66, >+ TokenNameREMAINDER = 5, >+ TokenNameXOR = 21, >+ TokenNameAND = 20, >+ TokenNameMULTIPLY = 4, >+ TokenNameOR = 22, >+ TokenNameTWIDDLE = 67, >+ TokenNameDIVIDE = 6, >+ TokenNameGREATER = 11, >+ TokenNameLESS = 7, >+ TokenNameLPAREN = 29, >+ TokenNameRPAREN = 28, >+ TokenNameLBRACE = 68, >+ TokenNameRBRACE = 31, >+ TokenNameLBRACKET = 16, >+ TokenNameRBRACKET = 70, >+ TokenNameSEMICOLON = 27, >+ TokenNameQUESTION = 23, >+ TokenNameCOLON = 65, >+ TokenNameCOMMA = 30, >+ TokenNameDOT = 3, >+ TokenNameEQUAL = 71, >+ TokenNameAT = 53, >+ TokenNameELLIPSIS = 107, >+ TokenNameEOF = 69, >+ TokenNameERROR = 110; >+} >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser1.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser1.rsc >index 2c68a20..c8d86dd 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser1.rsc >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser1.rsc >Binary files differ >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser10.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser10.rsc >index c0bd267..c5e7edf 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser10.rsc >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser10.rsc >Binary files differ >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser11.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser11.rsc >index e7c268c..5edc22c 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser11.rsc >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser11.rsc >Binary files differ >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser12.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser12.rsc >index 93630f6..6ea6cc3 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser12.rsc >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser12.rsc >Binary files differ >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser13.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser13.rsc >index fdcceda..b64633f 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser13.rsc >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser13.rsc >Binary files differ >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser14.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser14.rsc >index b02adc0..113160e 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser14.rsc >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser14.rsc >Binary files differ >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser15.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser15.rsc >index f1ca75e..a82641f 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser15.rsc >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser15.rsc >Binary files differ >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser16.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser16.rsc >index 98b3731..e57ff72 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser16.rsc >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser16.rsc >Binary files differ >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser17.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser17.rsc >index fc9a891..f39a839 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser17.rsc >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser17.rsc >Binary files differ >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser18.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser18.rsc >index 2ed1aae..aa0255e 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser18.rsc >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser18.rsc >Binary files differ >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser19.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser19.rsc >index 235e18f..34ffef8 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser19.rsc >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser19.rsc >@@ -1,2 +1,2 @@ >-hhgFFFDDgAAA!FdAfAID >+hhgFFFDDgAAA!FdAfAID > JJD!DDbGG_!!H!Ab!!!!55! >\ No newline at end of file >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser2.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser2.rsc >index 6cf6750..5c7a1bb 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser2.rsc >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser2.rsc >Binary files differ >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser20.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser20.rsc >index a6fa5a3..7a6589a 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser20.rsc >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser20.rsc >Binary files differ >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser21.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser21.rsc >index 05e26c7..705733d 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser21.rsc >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser21.rsc >Binary files differ >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser22.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser22.rsc >index 1477402..554be4b 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser22.rsc >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser22.rsc >Binary files differ >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser24.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser24.rsc >index 6a14007..3ca03ec 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser24.rsc >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser24.rsc >Binary files differ >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser3.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser3.rsc >index 6bb7a1e..f84aba4 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser3.rsc >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser3.rsc >Binary files differ >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser4.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser4.rsc >index 405f8e6..ddff383 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser4.rsc >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser4.rsc >Binary files differ >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser5.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser5.rsc >index 664cd36..440655f 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser5.rsc >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser5.rsc >Binary files differ >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser6.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser6.rsc >index 745efaf..46a0b80 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser6.rsc >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser6.rsc >Binary files differ >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser8.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser8.rsc >index c408cba..8b6d06f 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser8.rsc >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser8.rsc >Binary files differ >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser9.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser9.rsc >index b1ab05f..f327272 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser9.rsc >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser9.rsc >Binary files differ >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/readableNames.properties b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/readableNames.properties >index 629dc96..a2e9a35 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/readableNames.properties >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/readableNames.properties >@@ -1,15 +1,5 @@ >-############################################################################### >-# Copyright (c) 2011 IBM Corporation 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: >-# IBM Corporation - initial API and implementation >-############################################################################### > ,opt=, >-\;opt=; >+;opt=; > AbstractMethodDeclaration=MethodDeclaration > AdditionalBound1=AdditionalBound1 > AdditionalBound=AdditionalBound >@@ -109,6 +99,7 @@ > EnhancedForStatementHeaderInit=EnhancedForStatementHeaderInit > EnhancedForStatementNoShortIf=EnhancedForStatementNoShortIf > EnterCompilationUnit=EnterCompilationUnit >+EnterInstanceCreationArgumentList=EnterInstanceCreationArgumentList > EnterMemberValue=EnterMemberValue > EnterMemberValueArrayInitializer=EnterMemberValueArrayInitializer > EnterVariable=EnterVariable >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemHandler.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemHandler.java >index 6baad99..afa8a97 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemHandler.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemHandler.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -12,9 +12,12 @@ > > import org.eclipse.jdt.core.compiler.CategorizedProblem; > import org.eclipse.jdt.core.compiler.CharOperation; >+import org.eclipse.jdt.core.compiler.IProblem; > import org.eclipse.jdt.internal.compiler.CompilationResult; > import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy; > import org.eclipse.jdt.internal.compiler.IProblemFactory; >+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; >+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit; > import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; > import org.eclipse.jdt.internal.compiler.impl.ReferenceContext; > import org.eclipse.jdt.internal.compiler.util.Util; >@@ -114,6 +117,17 @@ > if (severity == ProblemSeverities.Ignore) > return; > >+ if ((severity & ProblemSeverities.Optional) != 0 && problemId != IProblem.Task) { >+ ICompilationUnit cu = unitResult.getCompilationUnit(); >+ try{ >+ if (cu != null && cu.ignoreOptionalProblems()) >+ return; >+ // workaround for illegal implementation of ICompilationUnit, see https://bugs.eclipse.org/372351 >+ } catch (AbstractMethodError ex) { >+ // continue >+ } >+ } >+ > // if no reference context, we need to abort from the current compilation process > if (referenceContext == null) { > if ((severity & ProblemSeverities.Error) != 0) { // non reportable error is fatal >@@ -150,6 +164,13 @@ > case ProblemSeverities.Error : > record(problem, unitResult, referenceContext); > if ((severity & ProblemSeverities.Fatal) != 0) { >+ // don't abort or tag as error if the error is suppressed >+ if (!referenceContext.hasErrors() && (severity & ProblemSeverities.Optional) != 0 && this.options.suppressOptionalErrors) { >+ CompilationUnitDeclaration unitDecl = referenceContext.getCompilationUnitDeclaration(); >+ if (unitDecl != null && unitDecl.isSuppressed(problem)) { >+ return; >+ } >+ } > referenceContext.tagAsHavingErrors(); > // should abort ? > int abortLevel; >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java >index a51fde1..3dd639a 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -8,9 +8,14 @@ > * Contributors: > * IBM Corporation - initial API and implementation > * Benjamin Muskalla - Contribution for bug 239066 >- * Stephan Herrmann - Contributions for >- * bug 236385 - >- * bug 338303 - Warning about Redundant assignment conflicts with definite assignment >+ * Stephan Herrmann - Contributions for >+ * bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used >+ * bug 338303 - Warning about Redundant assignment conflicts with definite assignment >+ * bug 349326 - [1.7] new warning for missing try-with-resources >+ * bug 186342 - [compiler][null] Using annotations for null checking >+ * bug 365519 - editorial cleanup after bug 186342 and bug 365387 >+ * bug 365662 - [compiler][null] warn on contradictory and redundant null annotations >+ * bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.problem; > >@@ -51,6 +56,7 @@ > import org.eclipse.jdt.internal.compiler.ast.EqualExpression; > import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall; > import org.eclipse.jdt.internal.compiler.ast.Expression; >+import org.eclipse.jdt.internal.compiler.ast.FakedTrackingVariable; > import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; > import org.eclipse.jdt.internal.compiler.ast.FieldReference; > import org.eclipse.jdt.internal.compiler.ast.ImportReference; >@@ -82,6 +88,7 @@ > import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; > import org.eclipse.jdt.internal.compiler.env.AccessRestriction; > import org.eclipse.jdt.internal.compiler.env.ICompilationUnit; >+import org.eclipse.jdt.internal.compiler.flow.FlowInfo; > import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; > import org.eclipse.jdt.internal.compiler.impl.ReferenceContext; > import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding; >@@ -91,6 +98,7 @@ > import org.eclipse.jdt.internal.compiler.lookup.InvocationSite; > import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding; > import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; >+import org.eclipse.jdt.internal.compiler.lookup.PackageBinding; > import org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding; > import org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding; > import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons; >@@ -285,6 +293,7 @@ > return CompilerOptions.NullReference; > > case IProblem.PotentialNullLocalVariableReference: >+ case IProblem.PotentialNullMessageSendReference: > return CompilerOptions.PotentialNullReference; > > case IProblem.RedundantLocalVariableNullAssignment: >@@ -293,7 +302,28 @@ > case IProblem.NonNullLocalVariableComparisonYieldsFalse: > case IProblem.NullLocalVariableComparisonYieldsFalse: > case IProblem.NullLocalVariableInstanceofYieldsFalse: >+ case IProblem.RedundantNullCheckOnNonNullMessageSend: > return CompilerOptions.RedundantNullCheck; >+ >+ case IProblem.RequiredNonNullButProvidedNull: >+ case IProblem.IllegalReturnNullityRedefinition: >+ case IProblem.IllegalRedefinitionToNonNullParameter: >+ case IProblem.IllegalDefinitionToNonNullParameter: >+ case IProblem.ParameterLackingNonNullAnnotation: >+ case IProblem.ParameterLackingNullableAnnotation: >+ case IProblem.CannotImplementIncompatibleNullness: >+ return CompilerOptions.NullSpecViolation; >+ >+ case IProblem.RequiredNonNullButProvidedPotentialNull: >+ return CompilerOptions.PotentialNullSpecViolation; >+ case IProblem.RequiredNonNullButProvidedUnknown: >+ return CompilerOptions.NullSpecInsufficientInfo; >+ case IProblem.RedundantNullAnnotation: >+ case IProblem.RedundantNullDefaultAnnotation: >+ case IProblem.RedundantNullDefaultAnnotationPackage: >+ case IProblem.RedundantNullDefaultAnnotationType: >+ case IProblem.RedundantNullDefaultAnnotationMethod: >+ return CompilerOptions.RedundantNullAnnotation; > > case IProblem.BoxingConversion : > case IProblem.UnboxingConversion : >@@ -426,6 +456,15 @@ > > case IProblem.MethodCanBePotentiallyStatic: > return CompilerOptions.MethodCanBePotentiallyStatic; >+ >+ case IProblem.UnclosedCloseable: >+ case IProblem.UnclosedCloseableAtExit: >+ return CompilerOptions.UnclosedCloseable; >+ case IProblem.PotentiallyUnclosedCloseable: >+ case IProblem.PotentiallyUnclosedCloseableAtExit: >+ return CompilerOptions.PotentiallyUnclosedCloseable; >+ case IProblem.ExplicitlyClosedAutoCloseable: >+ return CompilerOptions.ExplicitlyClosedAutoCloseable; > > case IProblem.RedundantSpecificationOfTypeArguments: > return CompilerOptions.RedundantSpecificationOfTypeArguments; >@@ -461,6 +500,7 @@ > case CompilerOptions.ParameterAssignment : > case CompilerOptions.MethodCanBeStatic : > case CompilerOptions.MethodCanBePotentiallyStatic : >+ case CompilerOptions.ExplicitlyClosedAutoCloseable : > return CategorizedProblem.CAT_CODE_STYLE; > > case CompilerOptions.MaskedCatchBlock : >@@ -482,6 +522,8 @@ > case CompilerOptions.ShouldImplementHashcode : > case CompilerOptions.DeadCode : > case CompilerOptions.UnusedObjectAllocation : >+ case CompilerOptions.UnclosedCloseable : >+ case CompilerOptions.PotentiallyUnclosedCloseable : > return CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM; > > case CompilerOptions.OverriddenPackageDefaultMethod : >@@ -527,7 +569,14 @@ > case CompilerOptions.ForbiddenReference : > case CompilerOptions.DiscouragedReference : > return CategorizedProblem.CAT_RESTRICTION; >- >+ >+ case CompilerOptions.NullSpecViolation : >+ case CompilerOptions.PotentialNullSpecViolation : >+ case CompilerOptions.NullSpecInsufficientInfo : >+ return CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM; >+ case CompilerOptions.RedundantNullAnnotation : >+ return CategorizedProblem.CAT_UNNECESSARY_CODE; >+ > default: > break categorizeOnIrritant; > } >@@ -2849,12 +2898,21 @@ > expression.sourceStart, > expression.sourceEnd); > } else { >- this.handle( >- IProblem.IncorrectSwitchType, >- new String[] {new String(testType.readableName())}, >- new String[] {new String(testType.shortReadableName())}, >- expression.sourceStart, >- expression.sourceEnd); >+ if (this.options.sourceLevel < ClassFileConstants.JDK1_5 && testType.isEnum()) { >+ this.handle( >+ IProblem.SwitchOnEnumNotBelow15, >+ new String[] {new String(testType.readableName())}, >+ new String[] {new String(testType.shortReadableName())}, >+ expression.sourceStart, >+ expression.sourceEnd); >+ } else { >+ this.handle( >+ IProblem.IncorrectSwitchType, >+ new String[] {new String(testType.readableName())}, >+ new String[] {new String(testType.shortReadableName())}, >+ expression.sourceStart, >+ expression.sourceEnd); >+ } > } > } else { > this.handle( >@@ -3214,6 +3272,27 @@ > typesAsString(shownConstructor, true), > new String(shownConstructor.declaringClass.shortReadableName()), > typesAsString(targetConstructor, true) }, >+ sourceStart, >+ sourceEnd); >+ return; >+ case ProblemReasons.VarargsElementTypeNotVisible : >+ problemConstructor = (ProblemMethodBinding) targetConstructor; >+ shownConstructor = problemConstructor.closestMatch; >+ TypeBinding varargsElementType = shownConstructor.parameters[shownConstructor.parameters.length - 1].leafComponentType(); >+ this.handle( >+ IProblem.VarargsElementTypeNotVisibleForConstructor, >+ new String[] { >+ new String(shownConstructor.declaringClass.sourceName()), >+ typesAsString(shownConstructor, false), >+ new String(shownConstructor.declaringClass.readableName()), >+ new String(varargsElementType.readableName()) >+ }, >+ new String[] { >+ new String(shownConstructor.declaringClass.sourceName()), >+ typesAsString(shownConstructor, true), >+ new String(shownConstructor.declaringClass.shortReadableName()), >+ new String(varargsElementType.shortReadableName()) >+ }, > sourceStart, > sourceEnd); > return; >@@ -3700,6 +3779,29 @@ > typesAsString(shownMethod, true), > new String(shownMethod.declaringClass.shortReadableName()), > typesAsString(method, true) }, >+ (int) (messageSend.nameSourcePosition >>> 32), >+ (int) messageSend.nameSourcePosition); >+ return; >+ case ProblemReasons.VarargsElementTypeNotVisible: // https://bugs.eclipse.org/bugs/show_bug.cgi?id=346042 >+ problemMethod = (ProblemMethodBinding) method; >+ if (problemMethod.closestMatch != null) { >+ shownMethod = problemMethod.closestMatch.original(); >+ } >+ TypeBinding varargsElementType = shownMethod.parameters[shownMethod.parameters.length - 1].leafComponentType(); >+ this.handle( >+ IProblem.VarargsElementTypeNotVisible, >+ new String[] { >+ new String(shownMethod.selector), >+ typesAsString(shownMethod, false), >+ new String(shownMethod.declaringClass.readableName()), >+ new String(varargsElementType.readableName()) >+ }, >+ new String[] { >+ new String(shownMethod.selector), >+ typesAsString(shownMethod, true), >+ new String(shownMethod.declaringClass.shortReadableName()), >+ new String(varargsElementType.shortReadableName()) >+ }, > (int) (messageSend.nameSourcePosition >>> 32), > (int) messageSend.nameSourcePosition); > return; >@@ -7497,7 +7599,9 @@ > > int severity = computeSeverity(IProblem.UnusedPrivateConstructor); > if (severity == ProblemSeverities.Ignore) return; >- >+ >+ if (excludeDueToAnnotation(constructorDecl.annotations)) return; >+ > MethodBinding constructor = constructorDecl.binding; > this.handle( > IProblem.UnusedPrivateConstructor, >@@ -7543,6 +7647,7 @@ > } > } > } >+ if (excludeDueToAnnotation(fieldDecl.annotations)) return; > this.handle( > IProblem.UnusedPrivateField, > new String[] { >@@ -7596,10 +7701,8 @@ > && CharOperation.equals(method.selector, TypeConstants.WRITEREPLACE)) { > return; > } >- if ((method.tagBits & (TagBits.AnnotationPostConstruct | TagBits.AnnotationPreDestroy)) != 0) { >- // PostConstruct and PreDestroy method are ignored >- return; >- } >+ if (excludeDueToAnnotation(methodDecl.annotations)) return; >+ > this.handle( > IProblem.UnusedPrivateMethod, > new String[] { >@@ -7616,10 +7719,43 @@ > methodDecl.sourceStart, > methodDecl.sourceEnd); > } >+ >+/** >+ * Returns true if a private member should not be warned as unused if >+ * annotated with a non-standard annotation. >+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=365437 >+ */ >+private boolean excludeDueToAnnotation(Annotation[] annotations) { >+ int annotationsLen = 0; >+ if (annotations != null) { >+ annotationsLen = annotations.length; >+ } else { >+ return false; >+ } >+ if (annotationsLen == 0) return false; >+ for (int i = 0; i < annotationsLen; i++) { >+ TypeBinding resolvedType = annotations[i].resolvedType; >+ if (resolvedType != null) { >+ switch (resolvedType.id) { >+ case TypeIds.T_JavaLangSuppressWarnings: >+ case TypeIds.T_JavaLangDeprecated: >+ case TypeIds.T_JavaLangSafeVarargs: >+ case TypeIds.T_ConfiguredAnnotationNonNull: >+ case TypeIds.T_ConfiguredAnnotationNullable: >+ case TypeIds.T_ConfiguredAnnotationNonNullByDefault: >+ break; >+ default: >+ // non-standard annotation found, don't warn >+ return true; >+ } >+ } >+ } >+ return false; >+} > public void unusedPrivateType(TypeDeclaration typeDecl) { > int severity = computeSeverity(IProblem.UnusedPrivateType); > if (severity == ProblemSeverities.Ignore) return; >- >+ if (excludeDueToAnnotation(typeDecl.annotations)) return; > ReferenceBinding type = typeDecl.binding; > this.handle( > IProblem.UnusedPrivateType, >@@ -7931,4 +8067,256 @@ > location.sourceEnd); > } > } >-} >\ No newline at end of file >+public void potentiallyUnclosedCloseable(FakedTrackingVariable trackVar, ASTNode location) { >+ String[] args = { String.valueOf(trackVar.name) }; >+ if (location == null) { >+ this.handle( >+ IProblem.PotentiallyUnclosedCloseable, >+ args, >+ args, >+ trackVar.sourceStart, >+ trackVar.sourceEnd); >+ } else { >+ this.handle( >+ IProblem.PotentiallyUnclosedCloseableAtExit, >+ args, >+ args, >+ location.sourceStart, >+ location.sourceEnd); >+ } >+} >+public void unclosedCloseable(FakedTrackingVariable trackVar, ASTNode location) { >+ String[] args = { String.valueOf(trackVar.name) }; >+ if (location == null) { >+ this.handle( >+ IProblem.UnclosedCloseable, >+ args, >+ args, >+ trackVar.sourceStart, >+ trackVar.sourceEnd); >+ } else { >+ this.handle( >+ IProblem.UnclosedCloseableAtExit, >+ args, >+ args, >+ location.sourceStart, >+ location.sourceEnd); >+ } >+} >+public void explicitlyClosedAutoCloseable(FakedTrackingVariable trackVar) { >+ String[] args = { String.valueOf(trackVar.name) }; >+ this.handle( >+ IProblem.ExplicitlyClosedAutoCloseable, >+ args, >+ args, >+ trackVar.sourceStart, >+ trackVar.sourceEnd); >+} >+ >+public void nullityMismatch(Expression expression, TypeBinding requiredType, int nullStatus, char[][] annotationName) { >+ int problemId = IProblem.RequiredNonNullButProvidedUnknown; >+ if ((nullStatus & FlowInfo.NULL) != 0) >+ problemId = IProblem.RequiredNonNullButProvidedNull; >+ if ((nullStatus & FlowInfo.POTENTIALLY_NULL) != 0) >+ problemId = IProblem.RequiredNonNullButProvidedPotentialNull; >+ String[] arguments = new String[] { >+ String.valueOf(CharOperation.concatWith(annotationName, '.')), >+ String.valueOf(requiredType.readableName()) >+ }; >+ String[] argumentsShort = new String[] { >+ String.valueOf(annotationName[annotationName.length-1]), >+ String.valueOf(requiredType.shortReadableName()) >+ }; >+ this.handle( >+ problemId, >+ arguments, >+ argumentsShort, >+ expression.sourceStart, >+ expression.sourceEnd); >+} >+public void illegalRedefinitionToNonNullParameter(Argument argument, ReferenceBinding declaringClass, char[][] inheritedAnnotationName) { >+ int sourceStart = argument.type.sourceStart; >+ if (argument.annotations != null) { >+ for (int i=0; i<argument.annotations.length; i++) { >+ Annotation annotation = argument.annotations[i]; >+ if ( annotation.resolvedType.id == TypeIds.T_ConfiguredAnnotationNullable >+ || annotation.resolvedType.id == TypeIds.T_ConfiguredAnnotationNonNull) >+ { >+ sourceStart = annotation.sourceStart; >+ break; >+ } >+ } >+ } >+ if (inheritedAnnotationName == null) { >+ this.handle( >+ IProblem.IllegalDefinitionToNonNullParameter, >+ new String[] { new String(argument.name), new String(declaringClass.readableName()) }, >+ new String[] { new String(argument.name), new String(declaringClass.shortReadableName()) }, >+ sourceStart, >+ argument.type.sourceEnd); >+ } else { >+ this.handle( >+ IProblem.IllegalRedefinitionToNonNullParameter, >+ new String[] { new String(argument.name), new String(declaringClass.readableName()), CharOperation.toString(inheritedAnnotationName)}, >+ new String[] { new String(argument.name), new String(declaringClass.shortReadableName()), new String(inheritedAnnotationName[inheritedAnnotationName.length-1])}, >+ sourceStart, >+ argument.type.sourceEnd); >+ } >+} >+public void parameterLackingNullAnnotation(Argument argument, ReferenceBinding declaringClass, boolean needNonNull, char[][] inheritedAnnotationName) { >+ this.handle( >+ needNonNull ? IProblem.ParameterLackingNonNullAnnotation : IProblem.ParameterLackingNullableAnnotation, >+ new String[] { new String(argument.name), new String(declaringClass.readableName()), CharOperation.toString(inheritedAnnotationName)}, >+ new String[] { new String(argument.name), new String(declaringClass.shortReadableName()), new String(inheritedAnnotationName[inheritedAnnotationName.length-1])}, >+ argument.type.sourceStart, >+ argument.type.sourceEnd); >+} >+public void illegalReturnRedefinition(AbstractMethodDeclaration abstractMethodDecl, >+ MethodBinding inheritedMethod, char[][] nonNullAnnotationName) >+{ >+ MethodDeclaration methodDecl = (MethodDeclaration) abstractMethodDecl; >+ StringBuffer methodSignature = new StringBuffer(); >+ methodSignature >+ .append(inheritedMethod.declaringClass.readableName()) >+ .append('.') >+ .append(inheritedMethod.readableName()); >+ >+ StringBuffer shortSignature = new StringBuffer(); >+ shortSignature >+ .append(inheritedMethod.declaringClass.shortReadableName()) >+ .append('.') >+ .append(inheritedMethod.shortReadableName()); >+ int sourceStart = methodDecl.returnType.sourceStart; >+ Annotation[] annotations = methodDecl.annotations; >+ Annotation annotation = findAnnotation(annotations, TypeIds.T_ConfiguredAnnotationNullable); >+ if (annotation != null) { >+ sourceStart = annotation.sourceStart; >+ } >+ this.handle( >+ IProblem.IllegalReturnNullityRedefinition, >+ new String[] { methodSignature.toString(), CharOperation.toString(nonNullAnnotationName)}, >+ new String[] { shortSignature.toString(), new String(nonNullAnnotationName[nonNullAnnotationName.length-1])}, >+ sourceStart, >+ methodDecl.returnType.sourceEnd); >+} >+public void messageSendPotentialNullReference(MethodBinding method, ASTNode location) { >+ String[] arguments = new String[] {new String(method.readableName())}; >+ this.handle( >+ IProblem.PotentialNullMessageSendReference, >+ arguments, >+ arguments, >+ location.sourceStart, >+ location.sourceEnd); >+} >+public void messageSendRedundantCheckOnNonNull(MethodBinding method, ASTNode location) { >+ String[] arguments = new String[] {new String(method.readableName()) }; >+ this.handle( >+ IProblem.RedundantNullCheckOnNonNullMessageSend, >+ arguments, >+ arguments, >+ location.sourceStart, >+ location.sourceEnd); >+} >+ >+public void cannotImplementIncompatibleNullness(MethodBinding currentMethod, MethodBinding inheritedMethod) { >+ int sourceStart = 0, sourceEnd = 0; >+ if (this.referenceContext instanceof TypeDeclaration) { >+ sourceStart = ((TypeDeclaration) this.referenceContext).sourceStart; >+ sourceEnd = ((TypeDeclaration) this.referenceContext).sourceEnd; >+ } >+ String[] problemArguments = { >+ new String(currentMethod.readableName()), >+ new String(currentMethod.declaringClass.readableName()), >+ new String(inheritedMethod.declaringClass.readableName()) >+ }; >+ String[] messageArguments = { >+ new String(currentMethod.shortReadableName()), >+ new String(currentMethod.declaringClass.shortReadableName()), >+ new String(inheritedMethod.declaringClass.shortReadableName()) >+ }; >+ this.handle( >+ IProblem.CannotImplementIncompatibleNullness, >+ problemArguments, >+ messageArguments, >+ sourceStart, >+ sourceEnd); >+} >+ >+public void nullAnnotationIsRedundant(AbstractMethodDeclaration sourceMethod, int i) { >+ int sourceStart, sourceEnd; >+ if (i == -1) { >+ MethodDeclaration methodDecl = (MethodDeclaration) sourceMethod; >+ Annotation annotation = findAnnotation(methodDecl.annotations, TypeIds.T_ConfiguredAnnotationNonNull); >+ sourceStart = annotation != null ? annotation.sourceStart : methodDecl.returnType.sourceStart; >+ sourceEnd = methodDecl.returnType.sourceEnd; >+ } else { >+ Argument arg = sourceMethod.arguments[i]; >+ sourceStart = arg.declarationSourceStart; >+ sourceEnd = arg.sourceEnd; >+ } >+ this.handle(IProblem.RedundantNullAnnotation, ProblemHandler.NoArgument, ProblemHandler.NoArgument, sourceStart, sourceEnd); >+} >+ >+public void nullDefaultAnnotationIsRedundant(ASTNode location, Annotation[] annotations, Binding outer) { >+ Annotation annotation = findAnnotation(annotations, TypeIds.T_ConfiguredAnnotationNonNullByDefault); >+ int start = annotation != null ? annotation.sourceStart : location.sourceStart; >+ int end = annotation != null ? annotation.sourceEnd : location.sourceStart; >+ String[] args = NoArgument; >+ String[] shortArgs = NoArgument; >+ if (outer != null) { >+ args = new String[] { new String(outer.readableName()) }; >+ shortArgs = new String[] { new String(outer.shortReadableName()) }; >+ } >+ int problemId = IProblem.RedundantNullDefaultAnnotation; >+ if (outer instanceof PackageBinding) { >+ problemId = IProblem.RedundantNullDefaultAnnotationPackage; >+ } else if (outer instanceof ReferenceBinding) { >+ problemId = IProblem.RedundantNullDefaultAnnotationType; >+ } else if (outer instanceof MethodBinding) { >+ problemId = IProblem.RedundantNullDefaultAnnotationMethod; >+ } >+ this.handle(problemId, args, shortArgs, start, end); >+} >+ >+public void contradictoryNullAnnotations(Annotation annotation) { >+ // when this error is triggered we can safely assume that both annotations have been configured >+ char[][] nonNullAnnotationName = this.options.nonNullAnnotationName; >+ char[][] nullableAnnotationName = this.options.nullableAnnotationName; >+ String[] arguments = { >+ new String(CharOperation.concatWith(nonNullAnnotationName, '.')), >+ new String(CharOperation.concatWith(nullableAnnotationName, '.')) >+ }; >+ String[] shortArguments = { >+ new String(nonNullAnnotationName[nonNullAnnotationName.length-1]), >+ new String(nullableAnnotationName[nullableAnnotationName.length-1]) >+ }; >+ this.handle(IProblem.ContradictoryNullAnnotations, arguments, shortArguments, annotation.sourceStart, annotation.sourceEnd); >+} >+ >+public void illegalAnnotationForBaseType(TypeReference type, Annotation[] annotations, char[] annotationName, long nullAnnotationTagBit) >+{ >+ int typeId = (nullAnnotationTagBit == TagBits.AnnotationNullable) >+ ? TypeIds.T_ConfiguredAnnotationNullable : TypeIds.T_ConfiguredAnnotationNonNull; >+ String[] args = new String[] { new String(annotationName), new String(type.getLastToken()) }; >+ Annotation annotation = findAnnotation(annotations, typeId); >+ int start = annotation != null ? annotation.sourceStart : type.sourceStart; >+ this.handle(IProblem.IllegalAnnotationForBaseType, >+ args, >+ args, >+ start, >+ type.sourceEnd); >+} >+ >+private Annotation findAnnotation(Annotation[] annotations, int typeId) { >+ if (annotations != null) { >+ // should have a @NonNull/@Nullable annotation, search for it: >+ int length = annotations.length; >+ for (int j=0; j<length; j++) { >+ if (annotations[j].resolvedType != null && annotations[j].resolvedType.id == typeId) { >+ return annotations[j]; >+ } >+ } >+ } >+ return null; >+} >+} >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties >index 2193910..265efae 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties >@@ -8,7 +8,12 @@ > # Contributors: > # IBM Corporation - initial API and implementation > # Benjamin Muskalla - Contribution for bug 239066 >-# Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 185682 - Increment/decrement operators mark local variables as read >+# Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for >+# bug 185682 - Increment/decrement operators mark local variables as read >+# bug 349326 - [1.7] new warning for missing try-with-resources >+# bug 186342 - [compiler][null] Using annotations for null checking >+# bug 365662 - [compiler][null] warn on contradictory and redundant null annotations >+# bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults > ############################################################################### > 0 = {0} > 1 = super cannot be used in java.lang.Object >@@ -143,7 +148,7 @@ > 162 = Cannot return from within an initializer > 163 = Initializer does not complete normally > 164 = Expression must return a value >-165 = Unreachable catch block for {0}. Only more specific exceptions are thrown and handled by previous catch block(s). >+165 = Unreachable catch block for {0}. Only more specific exceptions are thrown and they are handled by previous catch block(s). > 166 = The default case is already defined > 167 = Unreachable catch block for {0}. This exception is never thrown from the try statement body > 168 = Unhandled exception type {0} >@@ -287,7 +292,7 @@ > 343 = Illegal modifier for the interface field {0}.{1}; only public, static & final are permitted > 344 = The field {0} can only set one of public / protected / private > 345 = The field {0} can be either final or volatile, not both >-346 = The field {0} cannot be declared static; static fields can only be declared in static or top level types >+346 = The field {0} cannot be declared static in a non-static inner type, unless initialized with a constant expression > > ###[obsolete] 350 = {2} cannot be resolved (or is not a valid type) for the field {1}.{0} > ###[obsolete] 351 = The type {2} is not visible for the field {1}.{0} >@@ -615,6 +620,8 @@ > 804 = @SafeVarargs annotation cannot be applied to fixed arity method {0} > 805 = @SafeVarargs annotation cannot be applied to non-final instance method {0} > 806 = Type safety: Potential heap pollution via varargs parameter {0} >+807 = The method {0}({1}) of type {2} is not applicable as the formal varargs element type {3} is not accessible here >+808 = The constructor {0}({1}) of type {2} is not applicable as the formal varargs element type {3} is not accessible here > > ### GENERIC JAVADOC > 850 = Bound mismatch: The generic method {0}({1}) of type {2} is not applicable for the arguments ({3}). The inferred type {4} is not a valid substitute for the bounded parameter <{5} extends {6}> >@@ -644,6 +651,33 @@ > 882 = Unhandled exception type {0} thrown by automatic close() invocation on {1} > 883 = '<>' operator is not allowed for source level below 1.7 > 884 = Redundant specification of type arguments <{0}> >+885 = Potential resource leak: ''{0}'' may not be closed >+886 = Potential resource leak: ''{0}'' may not be closed at this location >+887 = Resource leak: ''{0}'' is never closed >+888 = Resource leak: ''{0}'' is not closed at this location >+889 = Resource ''{0}'' should be managed by try-with-resource >+890 = Cannot switch on an enum value for source level below 1.5. Only convertible int values are permitted >+ >+### NULL ANNOTATIONS >+910 = Type mismatch: required ''@{0} {1}'' but the provided value is null >+911 = Type mismatch: required ''@{0} {1}'' but the provided value can be null >+912 = Potential type mismatch: required ''@{0} {1}'' but nullness of the provided value is unknown >+#913 removed >+914 = The return type is incompatible with the @{1} return from {0} >+915 = Illegal redefinition of parameter {0}, inherited method from {1} declares this parameter as @{2} >+916 = Illegal redefinition of parameter {0}, inherited method from {1} does not constrain this parameter >+917 = Missing non-null annotation: inherited method from {1} declares this parameter as @{2} >+918 = Missing nullable annotation: inherited method from {1} declares this parameter as @{2} >+919 = Potential null pointer access: The method {0} may return null >+920 = Redundant null check: The method {0} cannot return null >+921 = The method {0} from {1} cannot implement the corresponding method from {2} due to incompatible nullness constraints >+922 = The nullness annotation is redundant with a default that applies to this location >+923 = The nullness annotation @{0} is not applicable for the primitive type {1} >+925 = Nullness default is redundant with the global default >+926 = Nullness default is redundant with a default specified for the enclosing package {0} >+927 = Nullness default is redundant with a default specified for the enclosing type {0} >+928 = Nullness default is redundant with a default specified for the enclosing method {0} >+929 = Contradictory null specification; only one of @{0} and @{1} can be specified at any location > > ### ELABORATIONS > ## Access restrictions >diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java >index 155a979..24f96ab 100644 >--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java >+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -102,6 +102,7 @@ > > /** > * Constant for indicating the AST API that handles JLS2. >+ * <p> > * This API is capable of handling all constructs > * in the Java language as described in the Java Language > * Specification, Second Edition (JLS2). >@@ -109,6 +110,7 @@ > * Java language, and the JLS2 API can be used to manipulate > * programs written in all versions of the Java language > * up to and including J2SE 1.4. >+ * </p> > * > * @since 3.0 > * @deprecated Clients should use the {@link #JLS4} AST API instead. >@@ -124,6 +126,7 @@ > > /** > * Constant for indicating the AST API that handles JLS3. >+ * <p> > * This API is capable of handling all constructs in the > * Java language as described in the Java Language > * Specification, Third Edition (JLS3). >@@ -131,21 +134,23 @@ > * Java language, and the JLS3 API can be used to manipulate > * programs written in all versions of the Java language > * up to and including J2SE 5 (aka JDK 1.5). >+ * </p> > * > * @since 3.1 > */ > public static final int JLS3 = 3; > > /** >- * Constant for indicating the AST API that handles JLS4. >+ * Constant for indicating the AST API that handles JLS4 (aka JLS7). >+ * <p> > * This API is capable of handling all constructs in the > * Java language as described in the Java Language >- * Specification, Third Edition (JLS3) plus all the new language >- * features described in the JSR334. >+ * Specification, Java SE 7 Edition (JLS7) as specified by JSR336. > * JLS4 is a superset of all earlier versions of the > * Java language, and the JLS4 API can be used to manipulate > * programs written in all versions of the Java language >- * up to and including J2SE 7 (aka JDK 1.7). >+ * up to and including Java SE 7 (aka JDK 1.7). >+ * </p> > * > * @since 3.7.1 > */ >@@ -163,7 +168,7 @@ > * into a compilation unit. This method is not intended to be called by clients. > * </p> > * >- * @param level the API level; one of the LEVEL constants >+ * @param level the API level; one of the <code>JLS*</code> level constants > * @param compilationUnitDeclaration an internal AST node for a compilation unit declaration > * @param source the string of the Java compilation unit > * @param options compiler options >@@ -194,7 +199,7 @@ > * into a compilation unit. This method is not intended to be called by clients. > * </p> > * >- * @param level the API level; one of the LEVEL constants >+ * @param level the API level; one of the <code>JLS*</code> level constants > * @param compilationUnitDeclaration an internal AST node for a compilation unit declaration > * @param options compiler options > * @param workingCopy the working copy that the AST is created from >@@ -245,11 +250,11 @@ > * AST level in all cases, even when dealing with source of earlier JDK versions like 1.3 or 1.4. > * </p> > * >- * @param level the API level; one of the LEVEL constants >+ * @param level the API level; one of the <code>JLS*</code> level constants > * @return new AST instance following the specified set of API rules. > * @exception IllegalArgumentException if: > * <ul> >- * <li>the API level is not one of the LEVEL constants</li> >+ * <li>the API level is not one of the <code>JLS*</code> level constants</li> > * </ul> > * @since 3.0 > */ >@@ -632,7 +637,7 @@ > * Creates a new Java abstract syntax tree > * (AST) following the specified set of API rules. > * >- * @param level the API level; one of the JLS* level constants >+ * @param level the API level; one of the <code>JLS*</code> level constants > * @since 3.0 > */ > private AST(int level) { >@@ -727,7 +732,7 @@ > /** > * Return the API level supported by this AST. > * >- * @return level the API level; one of the <code>JLS*</code>LEVEL >+ * @return level the API level; one of the <code>JLS*</code> level constants > * declared on <code>AST</code>; assume this set is open-ended > * @since 3.0 > */ >@@ -1060,7 +1065,6 @@ > * <ul> > * <li>the node belongs to a different AST</li> > * <li>the node already has a parent</li> >- * <li>a cycle in would be created</li> > * </ul> > */ > public ArrayType newArrayType(Type componentType) { >@@ -1071,28 +1075,26 @@ > > /** > * Creates and returns a new unparented array type node with the given >- * element type and number of dimensions. >+ * element type and number of (additional) dimensions. > * <p> > * Note that if the element type passed in is an array type, the > * element type of the result will not be the same as what was passed in. > * </p> > * >- * @param elementType the element type (never an array type) >+ * @param elementType the element type (can be an array type) > * @param dimensions the number of dimensions, a positive number > * @return a new unparented array type node > * @exception IllegalArgumentException if: > * <ul> > * <li>the node belongs to a different AST</li> > * <li>the node already has a parent</li> >- * <li>a cycle in would be created</li> > * <li>the element type is null</li> >- * <li>the element type is an array type</li> > * <li>the number of dimensions is lower than 1</li> > * <li>the number of dimensions is greater than 1000</li> > * </ul> > */ > public ArrayType newArrayType(Type elementType, int dimensions) { >- if (elementType == null || elementType.isArrayType()) { >+ if (elementType == null) { > throw new IllegalArgumentException(); > } > if (dimensions < 1 || dimensions > 1000) { >@@ -1386,7 +1388,6 @@ > * <ul> > * <li>the node belongs to a different AST</li> > * <li>the node already has a parent</li> >- * <li>a cycle in would be created</li> > * </ul> > */ > public ExpressionStatement newExpressionStatement(Expression expression) { >@@ -1426,7 +1427,6 @@ > * <ul> > * <li>the node belongs to a different AST</li> > * <li>the node already has a parent</li> >- * <li>a cycle in would be created</li> > * <li>the given fragment is null</li> > * </ul> > */ >@@ -2271,7 +2271,6 @@ > * <ul> > * <li>the node belongs to a different AST</li> > * <li>the node already has a parent</li> >- * <li>a cycle in would be created</li> > * </ul> > * @since 3.0 > */ >@@ -2302,7 +2301,6 @@ > * <ul> > * <li>the node belongs to a different AST</li> > * <li>the node already has a parent</li> >- * <li>a cycle in would be created</li> > * </ul> > */ > public TypeDeclarationStatement >@@ -2355,9 +2353,7 @@ > * <ul> > * <li>the node belongs to a different AST</li> > * <li>the node already has a parent</li> >- * <li>a cycle in would be created</li> > * <li>the given fragment is null</li> >- * <li>a cycle in would be created</li> > * </ul> > */ > public VariableDeclarationExpression >@@ -2402,7 +2398,6 @@ > * <ul> > * <li>the node belongs to a different AST</li> > * <li>the node already has a parent</li> >- * <li>a cycle in would be created</li> > * <li>the variable declaration fragment is null</li> > * </ul> > */ >diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java >index 714e6db..2faa9b2 100644 >--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java >+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2004, 2011 IBM Corporation and others. >+ * Copyright (c) 2004, 2012 IBM Corporation 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 >@@ -117,8 +117,8 @@ > * Creates a new object for creating a Java abstract syntax tree > * (AST) following the specified set of API rules. > * >- * @param level the API level; one of the LEVEL constants >- * declared on <code>AST</code> >+ * @param level the API level; one of the <code>.JLS*</code> level constants >+ * declared on {@link AST} > * @return new ASTParser instance > */ > public static ASTParser newParser(int level) { >@@ -213,8 +213,8 @@ > * N.B. This constructor is package-private. > * </p> > * >- * @param level the API level; one of the LEVEL constants >- * declared on <code>AST</code> >+ * @param level the API level; one of the <code>JLS*</code> level constants >+ * declared on {@link AST} > */ > ASTParser(int level) { > switch(level) { >diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnit.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnit.java >index 3765130..e599f9f 100644 >--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnit.java >+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnit.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -867,7 +867,7 @@ > > /** > * Enables the recording of changes to this compilation >- * unit and its descendents. The compilation unit must have >+ * unit and its descendants. The compilation unit must have > * been created by <code>ASTParser</code> and still be in > * its original state. Once recording is on, > * arbitrary changes to the subtree rooted at this compilation >diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnitResolver.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnitResolver.java >index 0fdbd0a..00b8222 100644 >--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnitResolver.java >+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnitResolver.java >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contribution for bug 363858 - [dom] early throwing of AbortCompilation causes NPE in CompilationUnitResolver > *******************************************************************************/ > package org.eclipse.jdt.core.dom; > >@@ -99,6 +100,7 @@ > DefaultBindingResolver.BindingTables bindingTables; > > boolean hasCompilationAborted; >+ CategorizedProblem abortProblem; > > private IProgressMonitor monitor; > >@@ -364,6 +366,7 @@ > removeUnresolvedBindings(unit); > } > this.hasCompilationAborted = true; >+ this.abortProblem = abortException.problem; > } > > public static void parse(ICompilationUnit[] compilationUnits, ASTRequestor astRequestor, int apiLevel, Map options, int flags, IProgressMonitor monitor) { >@@ -689,11 +692,16 @@ > // the bindings could not be resolved due to missing types in name environment > // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=86541 > CompilationUnitDeclaration unitDeclaration = parse(sourceUnit, nodeSearcher, options, flags); >- final int problemCount = unit.compilationResult.problemCount; >- if (problemCount != 0) { >- unitDeclaration.compilationResult.problems = new CategorizedProblem[problemCount]; >- System.arraycopy(unit.compilationResult.problems, 0, unitDeclaration.compilationResult.problems, 0, problemCount); >- unitDeclaration.compilationResult.problemCount = problemCount; >+ if (unit != null) { >+ final int problemCount = unit.compilationResult.problemCount; >+ if (problemCount != 0) { >+ unitDeclaration.compilationResult.problems = new CategorizedProblem[problemCount]; >+ System.arraycopy(unit.compilationResult.problems, 0, unitDeclaration.compilationResult.problems, 0, problemCount); >+ unitDeclaration.compilationResult.problemCount = problemCount; >+ } >+ } else if (resolver.abortProblem != null) { >+ unitDeclaration.compilationResult.problemCount = 1; >+ unitDeclaration.compilationResult.problems = new CategorizedProblem[] { resolver.abortProblem }; > } > return unitDeclaration; > } >diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java >index fcb5eb5..18a231a 100644 >--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java >+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java >@@ -1384,7 +1384,7 @@ > org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(pkg); > if (node instanceof ImportReference) { > ImportReference importReference = (ImportReference) node; >- Binding binding = this.scope.getTypeOrPackage(CharOperation.subarray(importReference.tokens, 0, importReference.tokens.length)); >+ Binding binding = this.scope.getOnlyPackage(CharOperation.subarray(importReference.tokens, 0, importReference.tokens.length)); > if ((binding != null) && (binding.isValidBinding())) { > if (binding instanceof ReferenceBinding) { > // this only happens if a type name has the same name as its package >diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TryStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TryStatement.java >index bd85911..79575e1 100644 >--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TryStatement.java >+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TryStatement.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ASTRewrite.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ASTRewrite.java >index ce07ee7..a8add6a 100644 >--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ASTRewrite.java >+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ASTRewrite.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2004, 2010 IBM Corporation and others. >+ * Copyright (c) 2004, 2012 IBM Corporation 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 >@@ -692,9 +692,10 @@ > > /** > * Creates and returns a placeholder node for the new locations of the given node. >- * After obtaining a placeholder, the node should then to be removed or replaced. >+ * After obtaining a placeholder, the node must be removed or replaced. > * The placeholder node can either be inserted as new or used to replace an >- * existing node. When the document is rewritten, the source code for the given >+ * existing node. The placeholder must be used somewhere in the AST and must not be dropped >+ * by subsequent modifications. When the document is rewritten, the source code for the given > * node is inserted into the output document at the position corresponding to the > * placeholder (indentation is adjusted). > * >diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ListRewrite.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ListRewrite.java >index 0e6dd82..a460d47 100644 >--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ListRewrite.java >+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ListRewrite.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2004, 2009 IBM Corporation and others. >+ * Copyright (c) 2004, 2011 IBM Corporation 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 >@@ -145,7 +145,7 @@ > > /** > * Inserts the given node into the list after the given element. >- * The existing node must be in the list, either as an original or as a new >+ * The existing node <code>previousElement</code> must be in the list, either as an original or as a new > * node that has been inserted. > * The inserted node must either be brand new (not part of the original AST) > * or a placeholder node (for example, one created by >@@ -156,20 +156,20 @@ > * a note that this node has been inserted into the list. > * > * @param node the node to insert >- * @param element the element after which the given node is to be inserted >+ * @param previousElement the element after which the given node is to be inserted > * @param editGroup the edit group in which to collect the corresponding > * text edits, or <code>null</code> if ungrouped > * @throws IllegalArgumentException if the node or element is null, > * or if the node is not part of this rewriter's AST, or if the inserted node >- * is not a new node (or placeholder), or if <code>element</code> is not a member >+ * is not a new node (or placeholder), or if <code>previousElement</code> is not a member > * of the list (original or new), or if the described modification is > * otherwise invalid > */ >- public void insertAfter(ASTNode node, ASTNode element, TextEditGroup editGroup) { >- if (node == null || element == null) { >+ public void insertAfter(ASTNode node, ASTNode previousElement, TextEditGroup editGroup) { >+ if (node == null || previousElement == null) { > throw new IllegalArgumentException(); > } >- int index= getEvent().getIndex(element, ListRewriteEvent.BOTH); >+ int index= getEvent().getIndex(previousElement, ListRewriteEvent.BOTH); > if (index == -1) { > throw new IllegalArgumentException("Node does not exist"); //$NON-NLS-1$ > } >@@ -178,7 +178,7 @@ > > /** > * Inserts the given node into the list before the given element. >- * The existing node must be in the list, either as an original or as a new >+ * The existing node <code>nextElement</code> must be in the list, either as an original or as a new > * node that has been inserted. > * The inserted node must either be brand new (not part of the original AST) > * or a placeholder node (for example, one created by >@@ -189,20 +189,20 @@ > * a note that this node has been inserted into the list. > * > * @param node the node to insert >- * @param element the element before which the given node is to be inserted >+ * @param nextElement the element before which the given node is to be inserted > * @param editGroup the edit group in which to collect the corresponding > * text edits, or <code>null</code> if ungrouped >- * @throws IllegalArgumentException if the node or element is null, >+ * @throws IllegalArgumentException if the node or next element is null, > * or if the node is not part of this rewriter's AST, or if the inserted node >- * is not a new node (or placeholder), or if <code>element</code> is not a member >+ * is not a new node (or placeholder), or if <code>nextElement</code> is not a member > * of the list (original or new), or if the described modification is > * otherwise invalid > */ >- public void insertBefore(ASTNode node, ASTNode element, TextEditGroup editGroup) { >- if (node == null || element == null) { >+ public void insertBefore(ASTNode node, ASTNode nextElement, TextEditGroup editGroup) { >+ if (node == null || nextElement == null) { > throw new IllegalArgumentException(); > } >- int index= getEvent().getIndex(element, ListRewriteEvent.BOTH); >+ int index= getEvent().getIndex(nextElement, ListRewriteEvent.BOTH); > if (index == -1) { > throw new IllegalArgumentException("Node does not exist"); //$NON-NLS-1$ > } >diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java >index 9394af1..b53e418 100644 >--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java >+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -1528,9 +1528,9 @@ > public boolean visit(TryStatement node) { > printIndent(); > this.buffer.append("try ");//$NON-NLS-1$ >- List resources = node.resources(); > if (node.getAST().apiLevel() >= AST.JLS4) { >- if (!node.resources().isEmpty()) { >+ List resources = node.resources(); >+ if (!resources.isEmpty()) { > this.buffer.append('('); > for (Iterator it = resources.iterator(); it.hasNext(); ) { > VariableDeclarationExpression variable = (VariableDeclarationExpression) it.next(); >diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java >index ffdab27..82701fc 100644 >--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java >+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java >@@ -881,10 +881,10 @@ > insertedPrefix = getLineDelimiter() + this.formatter.createIndentString(indent) + insertedPrefix.trim() + ' '; > } > doTextInsert(offset, insertedPrefix, editGroup); >- String lineInPrefix= getCurrentLine(prefix, prefix.length()); >- if (prefix.length() != lineInPrefix.length()) { >+ int lineStart= getCurrentLineStart(prefix, prefix.length()); >+ if (lineStart != 0) { > // prefix contains a new line: update the indent to the one used in the prefix >- indent= this.formatter.computeIndentUnits(lineInPrefix); >+ indent= this.formatter.computeIndentUnits(prefix.substring(lineStart)); > } > doTextInsert(offset, replacingNode, indent, true, editGroup); > doTextInsert(offset, strings[1], editGroup); >@@ -1316,7 +1316,12 @@ > } > currPos= offset; > } else { >- String destIndentString= this.formatter.getIndentString(getCurrentLine(formatted, offset)); >+ // If in the first line, there are cases (eg: catch clause) where the line will not be prefixed with >+ // proper indentation - see https://bugs.eclipse.org/bugs/show_bug.cgi?id=350285 >+ int lineOffset = getCurrentLineStart(formatted, offset); >+ String destIndentString = (lineOffset == 0) >+ ? this.formatter.createIndentString(initialIndentLevel) >+ : this.formatter.getIndentString(formatted.substring(lineOffset, offset)); > if (data instanceof CopyPlaceholderData) { // replace with a copy/move target > CopySourceInfo copySource= ((CopyPlaceholderData) data).copySource; > int srcIndentLevel= getIndent(copySource.getNode().getStartPosition()); >@@ -1349,17 +1354,16 @@ > return offset < formatted.length() && !IndentManipulation.isLineDelimiterChar(formatted.charAt(offset)); > } > >- private String getCurrentLine(String str, int pos) { >+ private int getCurrentLineStart(String str, int pos) { > for (int i= pos - 1; i>= 0; i--) { > char ch= str.charAt(i); > if (IndentManipulation.isLineDelimiterChar(ch)) { >- return str.substring(i + 1, pos); >+ return i+1; > } > } >- return str.substring(0, pos); >+ return 0; > } >- >- >+ > private void rewriteModifiers(ASTNode parent, StructuralPropertyDescriptor property, int offset) { > RewriteEvent event= getEvent(parent, property); > if (event == null || event.getChangeKind() != RewriteEvent.REPLACED) { >diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ImportRewriteAnalyzer.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ImportRewriteAnalyzer.java >index 5a43daf..06dc65c 100644 >--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ImportRewriteAnalyzer.java >+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ImportRewriteAnalyzer.java >@@ -758,9 +758,12 @@ > } else if (doStarImport && !currDecl.isOnDemand()) { > String simpleName = currDecl.getTypeQualifiedName(); > if (simpleName.indexOf('.') != -1) { >+ //If there is '.' in a Simple typename it is safe to assume that we are working with a Nested import > String str= getNewImportString(currDecl.getElementName(), isStatic, lineDelim); >- if (stringsToInsert.indexOf(str) == -1) { >- stringsToInsert.add(str); >+ String nextedStarImport = getNestedStarImport( >+ lineDelim, str); >+ if (stringsToInsert.indexOf(nextedStarImport) == -1) { >+ stringsToInsert.add(nextedStarImport); > } > } > } >@@ -770,6 +773,7 @@ > stringsToInsert.clear(); > currPos= offset + region.getLength(); > } else if (doStarImport && !currDecl.isOnDemand()) { >+ //If there is '.' in a Simple typename it is safe to assume that we are working with a Nested import > String simpleName = currDecl.getTypeQualifiedName(); > if (simpleName.indexOf('.') != -1) { > IRegion rangeBefore = currDecl.getPrecedingCommentRange(); >@@ -782,8 +786,10 @@ > trailingComment = buffer.getText(rangeAfter.getOffset(), rangeAfter.getLength()); > } > String str= getNewImportString(currDecl.getElementName(), isStatic, trailingComment, lineDelim); >- if (stringsToInsert.indexOf(str) == -1) { >- stringsToInsert.add(str); >+ String nextedStarImport = getNestedStarImport( >+ lineDelim, str); >+ if (stringsToInsert.indexOf(nextedStarImport) == -1) { >+ stringsToInsert.add(nextedStarImport); > } > } > } >@@ -977,7 +983,7 @@ > for (int i= 0; i < nImports; i++) { > ImportDeclEntry curr= packageEntry.getImportAt(i); > String simpleName = curr.getTypeQualifiedName(); >- if (simpleName.indexOf('.') != -1) { >+ if (simpleName.indexOf('.') != -1 &&!isStarImportAdded) { > // member type imports - we preserve it > IRegion rangeBefore = curr.getPrecedingCommentRange(); > if (rangeBefore != null) { >@@ -988,7 +994,10 @@ > if (rangeAfter != null) { > trailingComment = buffer.getText(rangeAfter.getOffset(), rangeAfter.getLength()); > } >- allImports.add(getNewImportString(curr.getElementName(), isStatic, trailingComment, lineDelim)); >+ String starImportString = getNestedImports(packageEntry.getName(), >+ simpleName); >+ allImports.add(getNewImportString(starImportString, isStatic, trailingComment, lineDelim)); >+ isStarImportAdded=true; > } else if (!isStarImportAdded) { > String starImportString= packageEntry.getName() + ".*"; //$NON-NLS-1$ > allImports.add(getNewImportString(starImportString, isStatic, lineDelim)); >@@ -1016,6 +1025,23 @@ > } > return (String[]) allImports.toArray(new String[allImports.size()]); > } >+ >+ private String getNestedStarImport(String lineDelim, String str) { >+ StringBuffer buff=new StringBuffer(); >+ buff.append(str.substring(0, str.lastIndexOf('.'))); >+ buff.append(".*;");//$NON-NLS-1$ >+ buff.append(lineDelim); >+ return buff.toString(); >+ } >+ >+ private String getNestedImports(String packageEntry,String simpleName) { >+ StringBuffer starImportString= new StringBuffer(); >+ starImportString.append(packageEntry); >+ starImportString.append(".");//$NON-NLS-1$ >+ starImportString.append(simpleName.substring(0, simpleName.lastIndexOf('.'))); >+ starImportString.append(".*"); //$NON-NLS-1$ >+ return starImportString.toString(); >+ } > > private static int getFirstTypeBeginPos(CompilationUnit root) { > List types= root.types(); >diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSkeleton.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSkeleton.java >index e894759..f0090b1 100644 >--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSkeleton.java >+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSkeleton.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contribution for bug 186342 - [compiler][null] Using annotations for null checking > *******************************************************************************/ > package org.eclipse.jdt.internal.eval; > >@@ -64,6 +65,9 @@ > public IBinaryAnnotation[] getParameterAnnotations(int index) { > return null; > } >+ public int getAnnotatedParametersCount() { >+ return 0; >+ } > public char[] getSelector() { > return this.selector; > } >diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/EvaluationContext.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/EvaluationContext.java >index ed5dc37..33c30f4 100644 >--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/EvaluationContext.java >+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/EvaluationContext.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -156,6 +156,9 @@ > } > public char[][] getPackageName() { > return null; >+ } >+ public boolean ignoreOptionalProblems() { >+ return false; > } > }; > >@@ -601,6 +604,9 @@ > public char[][] getPackageName() { > return null; > } >+ public boolean ignoreOptionalProblems() { >+ return false; >+ } > }; > SelectionEngine engine = new SelectionEngine(environment, mapper.getSelectionRequestor(requestor), options, owner); > engine.select(sourceUnit, mapper.startPosOffset + selectionSourceStart, mapper.startPosOffset + selectionSourceEnd); >diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/Evaluator.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/Evaluator.java >index de5c56e..de07b66 100644 >--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/Evaluator.java >+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/Evaluator.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -141,6 +141,9 @@ > public char[][] getPackageName() { > return null; > } >+ public boolean ignoreOptionalProblems() { >+ return false; >+ } > }}); > if (compilerRequestor.hasErrors) { > return null; >diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java >index 4889826..71e22b6 100644 >--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java >+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java >@@ -109,7 +109,6 @@ > import org.eclipse.jdt.internal.compiler.ast.Wildcard; > import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; > import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; >-import org.eclipse.jdt.internal.compiler.impl.Constant; > import org.eclipse.jdt.internal.compiler.lookup.BlockScope; > import org.eclipse.jdt.internal.compiler.lookup.ClassScope; > import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope; >@@ -3670,8 +3669,7 @@ > if (numberOfParens > 0) { > manageOpeningParenthesizedExpression(doubleLiteral, numberOfParens); > } >- Constant constant = doubleLiteral.constant; >- if (constant != null && constant.doubleValue() < 0) { >+ if (isNextToken(TerminalTokens.TokenNameMINUS)) { > this.scribe.printNextToken(TerminalTokens.TokenNameMINUS); > } > this.scribe.printNextToken(TerminalTokens.TokenNameDoubleLiteral); >@@ -3895,8 +3893,7 @@ > if (numberOfParens > 0) { > manageOpeningParenthesizedExpression(floatLiteral, numberOfParens); > } >- Constant constant = floatLiteral.constant; >- if (constant != null && floatLiteral.constant.floatValue() < 0) { >+ if (isNextToken(TerminalTokens.TokenNameMINUS)) { > this.scribe.printNextToken(TerminalTokens.TokenNameMINUS); > } > this.scribe.printNextToken(TerminalTokens.TokenNameFloatingPointLiteral); >@@ -4209,8 +4206,7 @@ > if (numberOfParens > 0) { > manageOpeningParenthesizedExpression(intLiteral, numberOfParens); > } >- Constant constant = intLiteral.constant; >- if (constant != null && constant.intValue() < 0) { >+ if (isNextToken(TerminalTokens.TokenNameMINUS)) { > this.scribe.printNextToken(TerminalTokens.TokenNameMINUS); > } > this.scribe.printNextToken(TerminalTokens.TokenNameIntegerLiteral); >@@ -4260,8 +4256,7 @@ > if (numberOfParens > 0) { > manageOpeningParenthesizedExpression(longLiteral, numberOfParens); > } >- Constant constant = longLiteral.constant; >- if (constant != null && constant.longValue() < 0) { >+ if (isNextToken(TerminalTokens.TokenNameMINUS)) { > this.scribe.printNextToken(TerminalTokens.TokenNameMINUS); > } > this.scribe.printNextToken(TerminalTokens.TokenNameLongLiteral); >diff --git a/org.eclipse.jdt.core/grammar/java.g b/org.eclipse.jdt.core/grammar/java.g >index 8eb0d0c..7e22ac1 100644 >--- a/org.eclipse.jdt.core/grammar/java.g >+++ b/org.eclipse.jdt.core/grammar/java.g >@@ -1234,28 +1234,32 @@ > /.$putCase consumeAllocationHeader(); $break ./ > /:$readableName AllocationHeader:/ > >-ClassInstanceCreationExpression ::= 'new' OnlyTypeArguments ClassType '(' ArgumentListopt ')' UnqualifiedClassBodyopt >+ClassInstanceCreationExpression ::= 'new' OnlyTypeArguments ClassType EnterInstanceCreationArgumentList '(' ArgumentListopt ')' UnqualifiedClassBodyopt > /.$putCase consumeClassInstanceCreationExpressionWithTypeArguments(); $break ./ > >-ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' UnqualifiedClassBodyopt >+ClassInstanceCreationExpression ::= 'new' ClassType EnterInstanceCreationArgumentList '(' ArgumentListopt ')' UnqualifiedClassBodyopt > /.$putCase consumeClassInstanceCreationExpression(); $break ./ > --1.1 feature > >-ClassInstanceCreationExpression ::= Primary '.' 'new' OnlyTypeArguments ClassType '(' ArgumentListopt ')' QualifiedClassBodyopt >+ClassInstanceCreationExpression ::= Primary '.' 'new' OnlyTypeArguments ClassType EnterInstanceCreationArgumentList '(' ArgumentListopt ')' QualifiedClassBodyopt > /.$putCase consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() ; $break ./ > >-ClassInstanceCreationExpression ::= Primary '.' 'new' ClassType '(' ArgumentListopt ')' QualifiedClassBodyopt >+ClassInstanceCreationExpression ::= Primary '.' 'new' ClassType EnterInstanceCreationArgumentList '(' ArgumentListopt ')' QualifiedClassBodyopt > /.$putCase consumeClassInstanceCreationExpressionQualified() ; $break ./ > > --1.1 feature >-ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' ClassType '(' ArgumentListopt ')' QualifiedClassBodyopt >+ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' ClassType EnterInstanceCreationArgumentList '(' ArgumentListopt ')' QualifiedClassBodyopt > /.$putCase consumeClassInstanceCreationExpressionQualified() ; $break ./ > /:$readableName ClassInstanceCreationExpression:/ > >-ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' OnlyTypeArguments ClassType '(' ArgumentListopt ')' QualifiedClassBodyopt >+ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' OnlyTypeArguments ClassType EnterInstanceCreationArgumentList '(' ArgumentListopt ')' QualifiedClassBodyopt > /.$putCase consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() ; $break ./ > /:$readableName ClassInstanceCreationExpression:/ > >+EnterInstanceCreationArgumentList ::= $empty >+/.$putCase consumeEnterInstanceCreationArgumentList(); $break ./ >+/:$readableName EnterInstanceCreationArgumentList:/ >+ > ClassInstanceCreationExpressionName ::= Name '.' > /.$putCase consumeClassInstanceCreationExpressionName() ; $break ./ > /:$readableName ClassInstanceCreationExpressionName:/ >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathAttribute.java >index d90ab15..dc2c826 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathAttribute.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathAttribute.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2005, 2010 IBM Corporation and others. >+ * Copyright (c) 2005, 2012 IBM Corporation 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 >@@ -58,6 +58,47 @@ > * @since 3.1 > */ > String JAVADOC_LOCATION_ATTRIBUTE_NAME = "javadoc_location"; //$NON-NLS-1$ >+ >+ /** >+ * Constant for the name of the index location attribute. >+ * >+ * <p>The value for this attribute has to be the string representation of a URL. >+ * It should point to an existing index file in a folder or a jar. The URL can also be of platform protocol.</p> >+ * >+ * @since 3.8 >+ */ >+ String INDEX_LOCATION_ATTRIBUTE_NAME = "index_location"; //$NON-NLS-1$ >+ >+ /** >+ * Constant for the name of the encoding to be used for source attachments. >+ * >+ * <p>The value of this attribute has to be a string representation of a valid encoding. The encoding >+ * for a source attachment is determined in the following order: </p> >+ * >+ * <ul> >+ * <li> Encoding explicitly set on the source file (java or zip), i.e. <code>org.eclipse.core.resources.IFile#getCharset(false)</code> </li> >+ * <li> Encoding set on the corresponding classpath entry </li> >+ * <li> If the source attachment is a folder, then the encoding determined by the file content if detectable </li> >+ * <li> If the source attachment is in the workspace, then the encoding of the enclosing resources</li> >+ * </ul> >+ * >+ * @see org.eclipse.core.resources.IFile#getCharset() >+ * @since 3.8 >+ */ >+ String SOURCE_ATTACHMENT_ENCODING = "source_encoding"; //$NON-NLS-1$ >+ >+ /** >+ * Constant for the name of the ignore optional compile problems attribute. >+ * This attribute is valid only for classpath entries describing source folders. >+ * The possible values for this attribute are <code>"true"</code> or >+ * <code>"false"</code>. When not present, <code>"false"</code> is assumed. >+ * If the value of this attribute is <code>"true"</code>, all optional problems >+ * from the source folder described by this classpath entry will not be reported >+ * by the compiler. >+ * >+ * @since 3.8 >+ */ >+ String IGNORE_OPTIONAL_PROBLEMS = "ignore_optional_problems"; //$NON-NLS-1$ > > /** > * Constant for the name of the optional attribute. The possible values >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelMarker.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelMarker.java >index dbc6e55..8d485ab 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelMarker.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelMarker.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -114,4 +114,13 @@ > * @since 2.0 > */ > String CLASSPATH_FILE_FORMAT = "classpathFileFormat"; //$NON-NLS-1$ >+ >+ /** >+ * Output overlapping another source attribute (value <code>"outputOverlappingSource"</code>). >+ * Used only on buildpath problem markers. The value of this attribute is >+ * either "true" or "false". >+ * >+ * @since 3.6.4 >+ */ >+ String OUTPUT_OVERLAPPING_SOURCE = "outputOverlappingSource"; //$NON-NLS-1$ > } >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelStatusConstants.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelStatusConstants.java >index 4cc2f45..a88db5e 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelStatusConstants.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelStatusConstants.java >@@ -345,4 +345,11 @@ > * @since 3.7 > */ > public static final int CANNOT_RETRIEVE_ATTACHED_JAVADOC_TIMEOUT = 1012; >+ >+ /** >+ * <p>Status constant indicating that the default or specific output folder is overlapping >+ * with another source location. </p> >+ * @since 3.6.4 >+ */ >+ public static final int OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE = 1013; > } >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaConventions.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaConventions.java >index 5d80813..8ae6fdc 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaConventions.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaConventions.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -581,11 +581,13 @@ > * <li> The project output location path cannot be null, must be absolute and located inside the project. > * <li> Specific output locations (specified on source entries) can be null, if not they must be located inside the project, > * <li> A project entry cannot refer to itself directly (that is, a project cannot prerequisite itself). >- * <li> Classpath entries or output locations cannot coincidate or be nested in each other, except for the following scenarii listed below: >- * <ul><li> A source folder can coincidate with its own output location, in which case this output can then contain library archives. >- * However, a specific output location cannot coincidate with any library or a distinct source folder than the one referring to it. </li> >+ * <li> Classpath entries or output locations cannot coincide or be nested in each other, except for the following scenarios listed below: >+ * <ul><li> A source folder can coincide with its own output location, in which case this output can then contain library archives. >+ * However, a specific output location cannot coincide with any library or a distinct source folder than the one referring to it.<br> >+ * Note: Since 3.8, this behavior can be overridden by configuring {@link JavaCore#CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE} >+ * </li> > * <li> A source/library folder can be nested in any source folder as long as the nested folder is excluded from the enclosing one. </li> >- * <li> An output location can be nested in a source folder, if the source folder coincidates with the project itself, or if the output >+ * <li> An output location can be nested in a source folder, if the source folder coincides with the project itself, or if the output > * location is excluded from the source folder. > * </ul> > * </ul> >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java >index 7a4a96a..1888747 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -83,6 +83,16 @@ > * Benjamin Muskalla - added COMPILER_PB_MISSING_SYNCHRONIZED_ON_INHERITED_METHOD > * Stephan Herrmann - added COMPILER_PB_UNUSED_OBJECT_ALLOCATION > * Stephan Herrmann - added COMPILER_PB_SUPPRESS_OPTIONAL_ERRORS >+ * Stephan Herrmann - added the following constants: >+ * COMPILER_PB_UNCLOSED_CLOSEABLE, >+ * COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE >+ * COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE >+ * COMPILER_ANNOTATION_NULL_ANALYSIS >+ * COMPILER_NULLABLE_ANNOTATION_NAME >+ * COMPILER_NONNULL_ANNOTATION_NAME >+ * COMPILER_PB_NULL_SPECIFICATION_VIOLATION >+ * COMPILER_PB_POTENTIAL_NULL_SPECIFICATION_VIOLATION >+ * COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO > *******************************************************************************/ > > package org.eclipse.jdt.core; >@@ -1357,6 +1367,276 @@ > */ > public static final String COMPILER_PB_POTENTIALLY_MISSING_STATIC_ON_METHOD = PLUGIN_ID + ".compiler.problem.reportMethodCanBePotentiallyStatic"; //$NON-NLS-1$ > /** >+ * Compiler option ID: Reporting a resource that is not closed properly. >+ * <p>When enabled, the compiler will issue an error or a warning if >+ * a local variable holds a value of type <code>java.lang.AutoCloseable</code> (compliance>=1.7) >+ * or a value of type <code>java.io.Closeable</code> (compliance<=1.6) and if >+ * flow analysis shows that the method <code>close()</code> is not invoked locally on that value. >+ * <dl> >+ * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.reportUnclosedCloseable"</code></dd> >+ * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd> >+ * <dt>Default:</dt><dd><code>"warning"</code></dd> >+ * </dl> >+ * @since 3.8 >+ * @category CompilerOptionID >+ */ >+ public static final String COMPILER_PB_UNCLOSED_CLOSEABLE = PLUGIN_ID + ".compiler.problem.unclosedCloseable"; //$NON-NLS-1$ >+ /** >+ * Compiler option ID: Reporting a resource that may not be closed properly. >+ * <p>When enabled, the compiler will issue an error or a warning if >+ * a local variable holds a value of type <code>java.lang.AutoCloseable</code> (compliance>=1.7) >+ * or a value of type <code>java.io.Closeable</code> (compliance<=1.6) and if >+ * flow analysis shows that the method <code>close()</code> is >+ * not invoked locally on that value for all execution paths. >+ * <dl> >+ * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.reportPotentiallyUnclosedCloseable"</code></dd> >+ * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd> >+ * <dt>Default:</dt><dd><code>"ignore"</code></dd> >+ * </dl> >+ * @since 3.8 >+ * @category CompilerOptionID >+ */ >+ public static final String COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE = PLUGIN_ID + ".compiler.problem.potentiallyUnclosedCloseable"; //$NON-NLS-1$ >+ /** >+ * Compiler option ID: Reporting a resource that is not managed by try-with-resources. >+ * <p>When enabled, the compiler will issue an error or a warning if a local variable >+ * holds a value of type <code>java.lang.AutoCloseable</code>, and if the method >+ * <code>close()</code> is explicitly invoked on that resource, but the resource is >+ * not managed by a try-with-resources block. >+ * <dl> >+ * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.reportPotentiallyUnclosedCloseable"</code></dd> >+ * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd> >+ * <dt>Default:</dt><dd><code>"ignore"</code></dd> >+ * </dl> >+ * @since 3.8 >+ * @category CompilerOptionID >+ */ >+ public static final String COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE = PLUGIN_ID + ".compiler.problem.explicitlyClosedAutoCloseable"; //$NON-NLS-1$ >+ /** >+ * Compiler option ID: Annotation-based Null Analysis. >+ * <p>This option controls whether the compiler will use null annotations for >+ * improved analysis of (potential) null references.</p> >+ * <p>When enabled, the compiler will interpret the annotation types defined using >+ * {@link #COMPILER_NONNULL_ANNOTATION_NAME} and {@link #COMPILER_NULLABLE_ANNOTATION_NAME} >+ * as specifying whether or not a given type includes the value <code>null</code>.</p> >+ * <p>The effect of these analyses is further controlled by the options >+ * {@link #COMPILER_PB_NULL_SPECIFICATION_VIOLATION}, >+ * {@link #COMPILER_PB_POTENTIAL_NULL_SPECIFICATION_VIOLATION} and >+ * {@link #COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO}. >+ * </p> >+ * <dl> >+ * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.annotation.nullanalysis"</code></dd> >+ * <dt>Possible values:</dt><dd><code>{ "disabled", "enabled" }</code></dd> >+ * <dt>Default:</dt><dd><code>"disabled"</code></dd> >+ * </dl> >+ * @since 3.8 >+ * @category CompilerOptionID >+ */ >+ public static final String COMPILER_ANNOTATION_NULL_ANALYSIS = PLUGIN_ID + ".compiler.annotation.nullanalysis"; //$NON-NLS-1$ >+ /** >+ * Compiler option ID: Name of Annotation Type for Nullable Types. >+ * <p>This option defines a fully qualified Java type name that the compiler may use >+ * to perform special null analysis.</p> >+ * <p>If the annotation specified by this option is applied to a type in a method >+ * signature or variable declaration, this will be interpreted as a specification >+ * that <code>null</code> is a legal value in that position. Currently supported >+ * positions are: method parameters, method return type and local variables.</p> >+ * <p>If a value whose type >+ * is annotated with this annotation is dereferenced without checking for null, >+ * the compiler will trigger a diagnostic as further controlled by >+ * {@link #COMPILER_PB_POTENTIAL_NULL_REFERENCE}.</p> >+ * <p>The compiler may furthermore check adherence to the null specification as >+ * further controlled by {@link #COMPILER_PB_NULL_SPECIFICATION_VIOLATION}, >+ * {@link #COMPILER_PB_POTENTIAL_NULL_SPECIFICATION_VIOLATION} and >+ * {@link #COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO}.</p> >+ * <p>This option only has an effect if the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled.</p> >+ * <dl> >+ * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.annotation.nullable"</code></dd> >+ * <dt>Possible values:</dt><dd>any legal, fully qualified Java type name; must resolve to an annotation type.</dd> >+ * <dt>Default:</dt><dd><code>"org.eclipse.jdt.annotation.Nullable"</code></dd> >+ * </dl> >+ * @since 3.8 >+ * @category CompilerOptionID >+ */ >+ public static final String COMPILER_NULLABLE_ANNOTATION_NAME = PLUGIN_ID + ".compiler.annotation.nullable"; //$NON-NLS-1$ >+ /** >+ * Compiler option ID: Name of Annotation Type for Non-Null Types. >+ * <p>This option defines a fully qualified Java type name that the compiler may use >+ * to perform special null analysis.</p> >+ * <p>If the annotation specified by this option is applied to a type in a method >+ * signature or variable declaration, this will be interpreted as a specification >+ * that <code>null</code> is <b>not</b> a legal value in that position. Currently >+ * supported positions are: method parameters, method return type and local variables.</p> >+ * <p>For values declared with this annotation, the compiler will never trigger a null >+ * reference diagnostic (as controlled by {@link #COMPILER_PB_POTENTIAL_NULL_REFERENCE} >+ * and {@link #COMPILER_PB_NULL_REFERENCE}), because the assumption is made that null >+ * will never occur at runtime in these positions.</p> >+ * <p>The compiler may furthermore check adherence to the null specification as further >+ * controlled by {@link #COMPILER_PB_NULL_SPECIFICATION_VIOLATION}, >+ * {@link #COMPILER_PB_POTENTIAL_NULL_SPECIFICATION_VIOLATION} and >+ * {@link #COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO}.</p> >+ * <p>This option only has an effect if the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled.</p> >+ * <dl> >+ * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.annotation.nonnull"</code></dd> >+ * <dt>Possible values:</dt><dd>any legal, fully qualified Java type name; must resolve to an annotation type.</dd> >+ * <dt>Default:</dt><dd><code>"org.eclipse.jdt.annotation.NonNull"</code></dd> >+ * </dl> >+ * @since 3.8 >+ * @category CompilerOptionID >+ */ >+ public static final String COMPILER_NONNULL_ANNOTATION_NAME = PLUGIN_ID + ".compiler.annotation.nonnull"; //$NON-NLS-1$ >+ /** >+ * Compiler option ID: Name of Annotation Type to specify a nullness default for unannotated types. >+ * <p>This option defines a fully qualified Java type name that the compiler may use >+ * to perform special null analysis.</p> >+ * <p>If the annotation is applied without an argument, all unannotated types in method signatures >+ * within the annotated element will be treated as if they were specified with the non-null annotation >+ * (see {@link #COMPILER_NONNULL_ANNOTATION_NAME}).</p> >+ * <p>If the annotation is applied with the constant <code>false</code> as its argument >+ * all corresponding defaults at outer scopes will be canceled for the annotated element. >+ * This includes defaults specified using this annotation type or a default defined using >+ * the compiler option {@link #COMPILER_NONNULL_IS_DEFAULT}.</p> >+ * <p>This option only has an effect if the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled.</p> >+ * <dl> >+ * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.annotation.nonnullbydefault"</code></dd> >+ * <dt>Possible values:</dt><dd>any legal, fully qualified Java type name; must resolve to an annotation type. >+ * That annotation type should have exactly one boolean parameter.</dd> >+ * <dt>Default:</dt><dd><code>"org.eclipse.jdt.annotation.NonNullByDefault"</code></dd> >+ * </dl> >+ * @since 3.8 >+ * @category CompilerOptionID >+ */ >+ public static final String COMPILER_NONNULL_BY_DEFAULT_ANNOTATION_NAME = PLUGIN_ID + ".compiler.annotation.nonnullbydefault"; //$NON-NLS-1$ >+ /** >+ * Compiler option ID: Globally specify non-null as the assumed default for unannotated types. >+ * <p>When enabled, this option globally achieves the same effect >+ * as specifying {@link #COMPILER_NONNULL_ANNOTATION_NAME} does for individual elements.</p> >+ * <p>This option only has an effect if the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled.</p> >+ * <dl> >+ * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.annotation.nonnullisdefault"</code></dd> >+ * <dt>Possible values:</dt><dd><code>{ "disabled", "enabled" }</code>.</dd> >+ * <dt>Default:</dt><dd><code>"disabled"</code></dd> >+ * </dl> >+ * @since 3.8 >+ * @category CompilerOptionID >+ */ >+ public static final String COMPILER_NONNULL_IS_DEFAULT = PLUGIN_ID + ".compiler.annotation.nonnullisdefault"; //$NON-NLS-1$ >+ /** >+ * Compiler option ID: Reporting Violations of Null Specifications. >+ * <p>Depending on this option, the compiler will issue either an error or a warning >+ * whenever one of the following situations is detected: >+ * <ol> >+ * <li>A method declared with a nonnull annotation returns an expression that is >+ * statically known to evaluate to a null value.</li> >+ * <li>An expression that is statically known to evaluate to a null value is passed >+ * as an argument in a method call where the corresponding parameter of the called >+ * method is declared with a nonnull annotation.</li> >+ * <li>An expression that is statically known to evaluate to a null value is assigned >+ * to a local variable that is declared with a nonnull annotation.</li> >+ * <li>A method that overrides an inherited method declared with a nonnull annotation >+ * tries to relax that contract by specifying a nullable annotation >+ * (prohibition of contravariant return).</li> >+ * <li>A method that overrides an inherited method which has a nullable declaration >+ * for at least one of its parameters, tries to tighten that null contract by >+ * specifying a nonnull annotation for its corresponding parameter >+ * (prohibition of covariant parameters).</li> >+ * </ol> >+ * </p> >+ * <p>The compiler options {@link #COMPILER_NONNULL_ANNOTATION_NAME} and >+ * {@link #COMPILER_NULLABLE_ANNOTATION_NAME} control which annotations the compiler >+ * shall interpret as nonnull or nullable annotations, respectively. >+ * </p> >+ * <p>This option only has an effect if the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled.</p> >+ * <dl> >+ * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.nullSpecViolation"</code></dd> >+ * <dt>Possible values:</dt><dd><code>{ "error", "warning" }</code></dd> >+ * <dt>Default:</dt><dd><code>"error"</code></dd> >+ * </dl> >+ * @since 3.8 >+ * @category CompilerOptionID >+ */ >+ public static final String COMPILER_PB_NULL_SPECIFICATION_VIOLATION = PLUGIN_ID + ".compiler.problem.nullSpecViolation"; //$NON-NLS-1$ >+ /** >+ * Compiler option ID: Reporting Violations of Null Specifications with Potential Null Value. >+ * <p>When enabled, the compiler will issue an error or a warning whenever one of the >+ * following situations is detected: >+ * <ol> >+ * <li>A method declared with a nonnull annotation returns an expression that is >+ * statically known to evaluate to a null value on some flow.</li> >+ * <li>An expression that is statically known to evaluate to a null value on some flow >+ * is passed as an argument in a method call where the corresponding parameter of >+ * the called method is declared with a nonnull annotation.</li> >+ * <li>An expression that is statically known to evaluate to a null value on some flow >+ * is assigned to a local variable that is declared with a nonnull annotation.</li> >+ * </ol> >+ * </p> >+ * <p>The compiler options {@link #COMPILER_NONNULL_ANNOTATION_NAME} and >+ * {@link #COMPILER_NULLABLE_ANNOTATION_NAME} control which annotations the compiler >+ * shall interpret as nonnull or nullable annotations, respectively. >+ * </p> >+ * <p>This option only has an effect if the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled.</p> >+ * <dl> >+ * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.potentialNullSpecViolation"</code></dd> >+ * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd> >+ * <dt>Default:</dt><dd><code>"error"</code></dd> >+ * </dl> >+ * @since 3.8 >+ * @category CompilerOptionID >+ */ >+ public static final String COMPILER_PB_POTENTIAL_NULL_SPECIFICATION_VIOLATION = PLUGIN_ID + ".compiler.problem.potentialNullSpecViolation"; //$NON-NLS-1$ >+ /** >+ * Compiler option ID: Reporting Insufficient Information for Analysing Adherence to Null Specifications. >+ * <p>When enabled, the compiler will issue an error or a warning whenever one of the >+ * following situations is detected: >+ * <ol> >+ * <li>A method declared with a nonnull annotation returns an expression for which >+ * insufficient nullness information is available for statically proving that no >+ * flow will pass a null value at runtime.</li> >+ * <li>An expression for which insufficient nullness information is available for >+ * statically proving that it will never evaluate to a null value at runtime >+ * is passed as an argument in a method call where the corresponding parameter of >+ * the called method is declared with a nonnull annotation.</li> >+ * <li>An expression for which insufficient nullness information is available for >+ * statically proving that it will never evaluate to a null value at runtime >+ * is assigned to a local variable that is declared with a nonnull annotation.</li> >+ * </ol> >+ * Insufficient nullness information is usually a consequence of using other unannotated >+ * variables or methods. >+ * </p> >+ * <p>The compiler options {@link #COMPILER_NONNULL_ANNOTATION_NAME} and >+ * {@link #COMPILER_NULLABLE_ANNOTATION_NAME} control which annotations the compiler >+ * shall interpret as nonnull or nullable annotations, respectively. >+ * </p> >+ * <p>This option only has an effect if the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled.</p> >+ * <dl> >+ * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.nullSpecInsufficientInfo"</code></dd> >+ * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd> >+ * <dt>Default:</dt><dd><code>"warning"</code></dd> >+ * </dl> >+ * @since 3.8 >+ * @category CompilerOptionID >+ */ >+ public static final String COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO = PLUGIN_ID + ".compiler.problem.nullSpecInsufficientInfo"; //$NON-NLS-1$ >+ /** >+ * Compiler option ID: Reporting Redundant Null Annotations. >+ * <p>When enabled, the compiler will issue an error or a warning when a non-null annotation >+ * (see {@link #COMPILER_NONNULL_ANNOTATION_NAME}) >+ * is applied although the same effect is already achieved by a default applicable at the >+ * current location. Such a default may be set by enabling the option >+ * {@link #COMPILER_NONNULL_IS_DEFAULT} or by using the annotation specified by the option >+ * {@link #COMPILER_NONNULL_BY_DEFAULT_ANNOTATION_NAME}. >+ * </p> >+ * <p>This option only has an effect if the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled.</p> >+ * <dl> >+ * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation"</code></dd> >+ * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd> >+ * <dt>Default:</dt><dd><code>"warning"</code></dd> >+ * </dl> >+ * @since 3.8 >+ * @category CompilerOptionID >+ */ >+ public static final String COMPILER_PB_REDUNDANT_NULL_ANNOTATION = PLUGIN_ID + ".compiler.problem.redundantNullAnnotation"; //$NON-NLS-1$ >+ /** > * Compiler option ID: Setting Source Compatibility Mode. > * <p>Specify whether which source level compatibility is used. From 1.4 on, <code>'assert'</code> is a keyword > * reserved for assertion support. Also note, than when toggling to 1.4 mode, the target VM >@@ -1828,6 +2108,19 @@ > * @category CoreOptionID > */ > public static final String CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS = PLUGIN_ID + ".classpath.multipleOutputLocations"; //$NON-NLS-1$ >+ /** >+ * Core option ID: Reporting an output location overlapping another source location. >+ * <p> Indicate the severity of the problem reported when a source entry's output location overlaps another >+ * source entry. </p> >+ * >+ * <dl> >+ * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource"</code></dd> >+ * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd> >+ * <dt>Default:</dt><dd><code>"error"</code></dd> >+ * </dl> >+ * @since 3.6.4 >+ */ >+ public static final String CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE = PLUGIN_ID + ".classpath.outputOverlappingAnotherSource"; //$NON-NLS-1$ > /** > * Core option ID: Set the timeout value for retrieving the method's parameter names from javadoc. > * <p>Timeout in milliseconds to retrieve the method's parameter names from javadoc. >@@ -3684,6 +3977,7 @@ > try { > if (JavaBuilder.DEBUG) > System.out.println("Touching " + project.getElementName()); //$NON-NLS-1$ >+ new ClasspathValidation((JavaProject) project).validate(); // https://bugs.eclipse.org/bugs/show_bug.cgi?id=287164 > project.getProject().touch(progressMonitor2); > } catch (CoreException e) { > // could not touch this project: ignore >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ByteCodeVisitorAdapter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ByteCodeVisitorAdapter.java >index dd894ad..c23af13 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ByteCodeVisitorAdapter.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ByteCodeVisitorAdapter.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -923,8 +923,9 @@ > // default behavior is to do nothing > } > /** >- * @see IBytecodeVisitor#_invokeinterface(int, int, byte, IConstantPoolEntry) >+ * @see IBytecodeVisitor#_invokedynamic(int, int, IConstantPoolEntry, IConstantPoolEntry) > * @since 3.6 >+ * @deprecated This has been replaced with {@link IBytecodeVisitor#_invokedynamic(int, int, IConstantPoolEntry)} > */ > public void _invokedynamic( > int pc, >@@ -934,6 +935,16 @@ > // default behavior is to do nothing > } > /** >+ * @see IBytecodeVisitor#_invokedynamic(int, int, IConstantPoolEntry) >+ * @since 3.8 >+ */ >+ public void _invokedynamic( >+ int pc, >+ int index, >+ IConstantPoolEntry invokeDynamicEntry) { >+ // default behavior is to do nothing >+ } >+ /** > * @see IBytecodeVisitor#_invokeinterface(int, int, byte, IConstantPoolEntry) > */ > public void _invokeinterface( >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAttributeNamesConstants.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAttributeNamesConstants.java >index e5dafa4..da838ec 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAttributeNamesConstants.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAttributeNamesConstants.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2008 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -140,4 +140,10 @@ > * @since 3.2 > */ > char[] STACK_MAP = "StackMap".toCharArray(); //$NON-NLS-1$ >+ >+ /** >+ * "BootstrapMethods" attribute (added in cldc1.0). >+ * @since 3.8 >+ */ >+ char[] BOOTSTRAP_METHODS = "BootstrapMethods".toCharArray(); //$NON-NLS-1$ > } >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBootstrapMethodsAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBootstrapMethodsAttribute.java >new file mode 100644 >index 0000000..d7bbd91 >--- /dev/null >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBootstrapMethodsAttribute.java >@@ -0,0 +1,40 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 IBM Corporation 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.core.util; >+ >+/** >+ * Description of a bootstrap methods attribute as described in the JVM specifications. >+ * >+ * This interface may be implemented by clients. >+ * >+ * @since 3.8 >+ */ >+public interface IBootstrapMethodsAttribute extends IClassFileAttribute { >+ >+ /** >+ * Answer back the number of bootstrap methods of this entry as specified in >+ * the JVM specifications. >+ * >+ * @return the number of bootstrap methods of this entry as specified in >+ * the JVM specifications >+ */ >+ int getBootstrapMethodsLength(); >+ >+ /** >+ * Answer back the bootstrap methods table of this entry as specified in >+ * the JVM specifications. Answer an empty array if none. >+ * >+ * @return the bootstrap methods table of this entry as specified in >+ * the JVM specifications. Answer an empty array if none >+ */ >+ IBootstrapMethodsEntry[] getBootstrapMethods(); >+ >+} >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBootstrapMethodsEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBootstrapMethodsEntry.java >new file mode 100644 >index 0000000..4078e85 >--- /dev/null >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBootstrapMethodsEntry.java >@@ -0,0 +1,24 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 IBM Corporation 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.core.util; >+ >+/** >+ * Description of a bootstrap method table entry as specified in the JVM specifications. >+ * >+ * This interface may be implemented by clients. >+ * >+ * @since 3.8 >+ */ >+public interface IBootstrapMethodsEntry { >+ >+ int getBootstrapMethodReference(); >+ int[] getBootstrapArguments(); >+} >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBytecodeVisitor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBytecodeVisitor.java >index 52ccb16..f36db8c 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBytecodeVisitor.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBytecodeVisitor.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -168,12 +168,20 @@ > IConstantPoolEntry constantClass); > /** > * @since 3.6 >+ * @deprecated This has been replaced with {@link #_invokedynamic(int, int, IConstantPoolEntry)} > */ > void _invokedynamic( > int pc, > int index, > IConstantPoolEntry nameEntry, > IConstantPoolEntry descriptorEntry); >+ /** >+ * @since 3.8 >+ */ >+ void _invokedynamic( >+ int pc, >+ int index, >+ IConstantPoolEntry invokeDynamic); > void _invokeinterface( > int pc, > int index, >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPool.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPool.java >index 6952606..9f57bb1 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPool.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPool.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -27,8 +27,7 @@ > int getConstantPoolCount(); > > /** >- * Answer back the type of the entry at the index @index >- * in the constant pool. >+ * Answer back the type of the entry at the given index in the constant pool. > * > * @param index the index of the entry in the constant pool > * @return the type of the entry at the index @index in the constant pool >@@ -36,11 +35,14 @@ > int getEntryKind(int index); > > /** >- * Answer back the entry at the index @index >- * in the constant pool. >+ * Answer back the entry at the given index in the constant pool. >+ * >+ * <p>The return value can be an instance of {@link IConstantPoolEntry2} if the value returned >+ * by {@link #getEntryKind(int)} is either {@link IConstantPoolConstant#CONSTANT_MethodHandle}, >+ * {@link IConstantPoolConstant#CONSTANT_MethodType} or {@link IConstantPoolConstant#CONSTANT_InvokeDynamic}.</p> > * > * @param index the index of the entry in the constant pool >- * @return the entry at the index @index in the constant pool >+ * @return the entry at the given index in the constant pool > */ > IConstantPoolEntry decodeEntry(int index); > } >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolConstant.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolConstant.java >index bc7cb54..ff6ed22 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolConstant.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolConstant.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2008 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -29,6 +29,18 @@ > int CONSTANT_Double = 6; > int CONSTANT_NameAndType = 12; > int CONSTANT_Utf8 = 1; >+ /** >+ * @since 3.8 >+ */ >+ int CONSTANT_MethodHandle = 15; >+ /** >+ * @since 3.8 >+ */ >+ int CONSTANT_MethodType = 16; >+ /** >+ * @since 3.8 >+ */ >+ int CONSTANT_InvokeDynamic = 18; > > int CONSTANT_Methodref_SIZE = 5; > int CONSTANT_Class_SIZE = 3; >@@ -41,5 +53,62 @@ > int CONSTANT_String_SIZE = 3; > int CONSTANT_Utf8_SIZE = 3; > int CONSTANT_NameAndType_SIZE = 5; >+ /** >+ * @since 3.8 >+ */ >+ int CONSTANT_MethodHandle_SIZE = 4; >+ /** >+ * @since 3.8 >+ */ >+ int CONSTANT_MethodType_SIZE = 3; >+ /** >+ * @since 3.8 >+ */ >+ int CONSTANT_InvokeDynamic_SIZE = 5; > >+ /** >+ * The constant is described at 5.4.3.5 in the Java 7 VM specification (part 3). >+ * @since 3.8 >+ */ >+ int METHOD_TYPE_REF_GetField = 1; >+ /** >+ * The constant is described at 5.4.3.5 in the Java 7 VM specification (part 3). >+ * @since 3.8 >+ */ >+ int METHOD_TYPE_REF_GetStatic = 2; >+ /** >+ * The constant is described at 5.4.3.5 in the Java 7 VM specification (part 3). >+ * @since 3.8 >+ */ >+ int METHOD_TYPE_REF_PutField = 3; >+ /** >+ * The constant is described at 5.4.3.5 in the Java 7 VM specification (part 3). >+ * @since 3.8 >+ */ >+ int METHOD_TYPE_REF_PutStatic = 4; >+ /** >+ * The constant is described at 5.4.3.5 in the Java 7 VM specification (part 3). >+ * @since 3.8 >+ */ >+ int METHOD_TYPE_REF_InvokeVirtual = 5; >+ /** >+ * The constant is described at 5.4.3.5 in the Java 7 VM specification (part 3). >+ * @since 3.8 >+ */ >+ int METHOD_TYPE_REF_InvokeStatic = 6; >+ /** >+ * The constant is described at 5.4.3.5 in the Java 7 VM specification (part 3). >+ * @since 3.8 >+ */ >+ int METHOD_TYPE_REF_InvokeSpecial = 7; >+ /** >+ * The constant is described at 5.4.3.5 in the Java 7 VM specification (part 3). >+ * @since 3.8 >+ */ >+ int METHOD_TYPE_REF_NewInvokeSpecial = 8; >+ /** >+ * The constant is described at 5.4.3.5 in the Java 7 VM specification (part 3). >+ * @since 3.8 >+ */ >+ int METHOD_TYPE_REF_InvokeInterface = 9; > } >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolEntry.java >index 487ad82..c75bd40 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolEntry.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolEntry.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -32,6 +32,7 @@ > * The value is unspecified otherwise. > * > * @return the name index for a CONSTANT_Class type entry >+ * @see IConstantPoolConstant#CONSTANT_Class > */ > int getClassInfoNameIndex(); > >@@ -42,16 +43,25 @@ > * > * @return the class index for a CONSTANT_Fieldref, > * CONSTANT_Methodref, CONSTANT_InterfaceMethodref type entry >+ * @see IConstantPoolConstant#CONSTANT_Fieldref >+ * @see IConstantPoolConstant#CONSTANT_Methodref >+ * @see IConstantPoolConstant#CONSTANT_InterfaceMethodref > */ > int getClassIndex(); > > /** > * Returns the nameAndType index for a CONSTANT_Fieldref, >- * CONSTANT_Methodref, CONSTANT_InterfaceMethodref type entry. >+ * CONSTANT_Methodref, CONSTANT_InterfaceMethodref, >+ * CONSTANT_InvokeDynamic type entry. > * The value is unspecified otherwise. > * > * @return the nameAndType index for a CONSTANT_Fieldref, >- * CONSTANT_Methodref, CONSTANT_InterfaceMethodref type entry >+ * CONSTANT_Methodref, CONSTANT_InterfaceMethodref, >+ * CONSTANT_InvokeDynamic type entry >+ * @see IConstantPoolConstant#CONSTANT_Fieldref >+ * @see IConstantPoolConstant#CONSTANT_Methodref >+ * @see IConstantPoolConstant#CONSTANT_InterfaceMethodref >+ * @see IConstantPoolConstant#CONSTANT_InvokeDynamic > */ > int getNameAndTypeIndex(); > >@@ -60,6 +70,7 @@ > * The value is unspecified otherwise. > * > * @return the string index for a CONSTANT_String type entry >+ * @see IConstantPoolConstant#CONSTANT_String > */ > int getStringIndex(); > >@@ -68,6 +79,7 @@ > * Returns null otherwise. > * > * @return the string value for a CONSTANT_String type entry >+ * @see IConstantPoolConstant#CONSTANT_String > */ > String getStringValue(); > >@@ -76,6 +88,7 @@ > * The value is unspecified otherwise. > * > * @return the integer value for a CONSTANT_Integer type entry >+ * @see IConstantPoolConstant#CONSTANT_Integer > */ > int getIntegerValue(); > >@@ -84,6 +97,7 @@ > * The value is unspecified otherwise. > * > * @return the float value for a CONSTANT_Float type entry >+ * @see IConstantPoolConstant#CONSTANT_Float > */ > float getFloatValue(); > >@@ -92,6 +106,7 @@ > * The value is unspecified otherwise. > * > * @return the double value for a CONSTANT_Double type entry >+ * @see IConstantPoolConstant#CONSTANT_Double > */ > double getDoubleValue(); > >@@ -100,6 +115,7 @@ > * The value is unspecified otherwise. > * > * @return the long value for a CONSTANT_Long type entry >+ * @see IConstantPoolConstant#CONSTANT_Long > */ > long getLongValue(); > >@@ -108,6 +124,7 @@ > * The value is unspecified otherwise. > * > * @return the descriptor index for a CONSTANT_NameAndType type entry >+ * @see IConstantPoolConstant#CONSTANT_NameAndType > */ > int getNameAndTypeInfoDescriptorIndex(); > >@@ -116,6 +133,7 @@ > * The value is unspecified otherwise. > * > * @return the name index for a CONSTANT_NameAndType type entry >+ * @see IConstantPoolConstant#CONSTANT_NameAndType > */ > int getNameAndTypeInfoNameIndex(); > >@@ -124,6 +142,7 @@ > * Returns null otherwise. > * > * @return the class name for a CONSTANT_Class type entry >+ * @see IConstantPoolConstant#CONSTANT_Class > */ > char[] getClassInfoName(); > >@@ -134,6 +153,9 @@ > * > * @return the class name for a CONSTANT_Fieldref, > * CONSTANT_Methodref, CONSTANT_InterfaceMethodref type entry >+ * @see IConstantPoolConstant#CONSTANT_Fieldref >+ * @see IConstantPoolConstant#CONSTANT_Methodref >+ * @see IConstantPoolConstant#CONSTANT_InterfaceMethodref > */ > char[] getClassName(); > >@@ -142,16 +164,20 @@ > * Returns null otherwise. > * > * @return the field name for a CONSTANT_Fieldref type entry >+ * @see IConstantPoolConstant#CONSTANT_Fieldref > */ > char[] getFieldName(); > > /** >- * Returns the field name for a CONSTANT_Methodref or CONSTANT_InterfaceMethodred >- * type entry. >+ * Returns the field name for a CONSTANT_Methodref, CONSTANT_InterfaceMethodref >+ * or CONSTANT_InvokeDynamic type entry. > * Returns null otherwise. > * >- * @return the field name for a CONSTANT_Methodref or CONSTANT_InterfaceMethodred >- * type entry >+ * @return the method name for a CONSTANT_Methodref, CONSTANT_InterfaceMethodref >+ * or CONSTANT_InvokeDynamic type entry >+ * @see IConstantPoolConstant#CONSTANT_Methodref >+ * @see IConstantPoolConstant#CONSTANT_InterfaceMethodref >+ * @see IConstantPoolConstant#CONSTANT_InvokeDynamic > */ > char[] getMethodName(); > >@@ -162,18 +188,27 @@ > * > * @return the field descriptor value for a CONSTANT_Fieldref type entry. This value > * is set only when decoding the CONSTANT_Fieldref entry >+ * @see IConstantPoolConstant#CONSTANT_Fieldref > */ > char[] getFieldDescriptor(); > > /** > * Returns the method descriptor value for a CONSTANT_Methodref or > * CONSTANT_InterfaceMethodref type entry. This value is set only when decoding the >- * CONSTANT_Methodref or CONSTANT_InterfaceMethodref entry. >+ * CONSTANT_Methodref, CONSTANT_InterfaceMethodref, CONSTANT_MethodType >+ * or CONSTANT_InvokeDynamic entry. >+ * > * Returns null otherwise. > * >- * @return the method descriptor value for a CONSTANT_Methodref or >+ * @return the method descriptor value for a CONSTANT_Methodref, > * CONSTANT_InterfaceMethodref type entry. This value is set only when decoding the >- * CONSTANT_Methodref or CONSTANT_InterfaceMethodref entry >+ * CONSTANT_Methodref, CONSTANT_InterfaceMethodref, CONSTANT_MethodType >+ * or CONSTANT_InvokeDynamic entry >+ * >+ * @see IConstantPoolConstant#CONSTANT_Methodref >+ * @see IConstantPoolConstant#CONSTANT_InterfaceMethodref >+ * @see IConstantPoolConstant#CONSTANT_MethodType >+ * @see IConstantPoolConstant#CONSTANT_InvokeDynamic > */ > char[] getMethodDescriptor(); > >@@ -184,6 +219,7 @@ > * > * @return the utf8 value for a CONSTANT_Utf8 type entry. This value is set only when > * decoding a UTF8 entry >+ * @see IConstantPoolConstant#CONSTANT_Utf8 > */ > char[] getUtf8Value(); > >@@ -194,6 +230,7 @@ > * > * @return the utf8 length for a CONSTANT_Utf8 type entry. This value is set only when > * decoding a UTF8 entry >+ * @see IConstantPoolConstant#CONSTANT_Utf8 > */ > int getUtf8Length(); > } >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolEntry2.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolEntry2.java >new file mode 100644 >index 0000000..3b4984b >--- /dev/null >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolEntry2.java >@@ -0,0 +1,59 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 IBM Corporation 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.core.util; >+ >+/** >+ * Description of the new constant pool entry as described in the JVM specifications >+ * added for Java 7 support. >+ * Its contents is initialized according to its kind. >+ * >+ * This interface may be implemented by clients. >+ * >+ * @since 3.8 >+ */ >+public interface IConstantPoolEntry2 extends IConstantPoolEntry { >+ /** >+ * Returns the descriptor index. This value is set only when decoding a MethodType entry. >+ * The value is unspecified otherwise. The corresponding UTF8 value can be retrieved by using >+ * {@link #getMethodDescriptor()}. >+ * >+ * @return the descriptor index. This value is set only when decoding a MethodType entry. >+ * @see IConstantPoolConstant#CONSTANT_MethodType >+ */ >+ int getDescriptorIndex(); >+ >+ /** >+ * Returns the reference kind. This value is set only when decoding a MethodHandle entry. >+ * The value is unspecified otherwise. >+ * >+ * @return the reference kind. This value is set only when decoding a MethodHandle entry. >+ * @see IConstantPoolConstant#CONSTANT_MethodHandle >+ */ >+ int getReferenceKind(); >+ >+ /** >+ * Returns the reference index. This value is set only when decoding a MethodHandle entry. >+ * The value is unspecified otherwise. >+ * >+ * @return the reference kind. This value is set only when decoding a MethodHandle entry. >+ * @see IConstantPoolConstant#CONSTANT_MethodHandle >+ */ >+ int getReferenceIndex(); >+ >+ /** >+ * Returns the bootstrap method attribute index. This value is set only when decoding a InvokeDynamic entry. >+ * The value is unspecified otherwise. >+ * >+ * @return the reference kind. This value is set only when decoding a MethodHandle entry. >+ * @see IConstantPoolConstant#CONSTANT_InvokeDynamic >+ */ >+ int getBootstrapMethodAttributeIndex(); >+} >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/DocumentElementParser.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/DocumentElementParser.java >index cea4763..597b56c 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/DocumentElementParser.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/DocumentElementParser.java >@@ -623,6 +623,9 @@ > arg.annotations = new Annotation[length], > 0, > length); >+ RecoveredType currentRecoveryType = this.currentRecoveryType(); >+ if (currentRecoveryType != null) >+ currentRecoveryType.annotationsConsumed(arg.annotations); > } > pushOnAstStack(arg); > this.intArrayPtr--; >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceJavadocParser.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceJavadocParser.java >index 6f96497..00461e7 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceJavadocParser.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceJavadocParser.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -93,10 +93,10 @@ > this.index++; > while (this.source[this.index] == 'u') > this.index++; >- if (!(((c1 = ScannerHelper.getNumericValue(this.source[this.index++])) > 15 || c1 < 0) >- || ((c2 = ScannerHelper.getNumericValue(this.source[this.index++])) > 15 || c2 < 0) >- || ((c3 = ScannerHelper.getNumericValue(this.source[this.index++])) > 15 || c3 < 0) >- || ((c4 = ScannerHelper.getNumericValue(this.source[this.index++])) > 15 || c4 < 0))) { >+ if (!(((c1 = ScannerHelper.getHexadecimalValue(this.source[this.index++])) > 15 || c1 < 0) >+ || ((c2 = ScannerHelper.getHexadecimalValue(this.source[this.index++])) > 15 || c2 < 0) >+ || ((c3 = ScannerHelper.getHexadecimalValue(this.source[this.index++])) > 15 || c3 < 0) >+ || ((c4 = ScannerHelper.getHexadecimalValue(this.source[this.index++])) > 15 || c4 < 0))) { > first = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4); > } else { > this.index = pos; >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/SourceTypeConverter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/SourceTypeConverter.java >index a5e4af3..ffae433 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/SourceTypeConverter.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/SourceTypeConverter.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -7,7 +7,9 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >- * Stephan Herrmann <stephan@cs.tu-berlin.de> - TypeConverters don't set enclosingType - https://bugs.eclipse.org/bugs/show_bug.cgi?id=320841 >+ * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for >+ * Bug 320841 - TypeConverters don't set enclosingType >+ * Bug 353474 - type converters should include more annotations > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.parser; > >@@ -28,6 +30,7 @@ > import org.eclipse.jdt.core.IAnnotation; > import org.eclipse.jdt.core.IImportDeclaration; > import org.eclipse.jdt.core.IJavaElement; >+import org.eclipse.jdt.core.ILocalVariable; > import org.eclipse.jdt.core.ISourceRange; > import org.eclipse.jdt.core.JavaModelException; > import org.eclipse.jdt.core.Signature; >@@ -373,6 +376,7 @@ > char[][] argumentNames = methodInfo.getArgumentNames(); > int argumentCount = argumentTypeSignatures == null ? 0 : argumentTypeSignatures.length; > if (argumentCount > 0) { >+ ILocalVariable[] parameters = methodHandle.getParameters(); > long position = ((long) start << 32) + end; > method.arguments = new Argument[argumentCount]; > for (int i = 0; i < argumentCount; i++) { >@@ -387,6 +391,11 @@ > typeReference, > ClassFileConstants.AccDefault); > // do not care whether was final or not >+ // convert 1.5 specific constructs only if compliance is 1.5 or above >+ if (this.has1_5Compliance) { >+ /* convert annotations */ >+ method.arguments[i].annotations = convertAnnotations(parameters[i]); >+ } > } > } > >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BasicCompilationUnit.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BasicCompilationUnit.java >index 3b7e3ac..11cdaa3 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BasicCompilationUnit.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BasicCompilationUnit.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -133,6 +133,9 @@ > public char[][] getPackageName() { > return this.packageName; > } >+public boolean ignoreOptionalProblems() { >+ return false; >+} > public String toString(){ > return "CompilationUnit: "+new String(this.fileName); //$NON-NLS-1$ > } >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMember.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMember.java >index 94e6db1..3f6d742 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMember.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMember.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -86,12 +86,6 @@ > } > if ((tagBits & TagBits.AnnotationSafeVarargs) != 0) { > annotations.add(getAnnotation(TypeConstants.JAVA_LANG_SAFEVARARGS)); >- } >- if ((tagBits & TagBits.AnnotationPostConstruct) != 0) { >- annotations.add(getAnnotation(TypeConstants.JAVAX_ANNOTATION_POSTCONSTRUCT)); >- } >- if ((tagBits & TagBits.AnnotationPreDestroy) != 0) { >- annotations.add(getAnnotation(TypeConstants.JAVAX_ANNOTATION_PREDESTROY)); > } > // note that JAVA_LANG_SUPPRESSWARNINGS and JAVA_LANG_OVERRIDE cannot appear in binaries > return (IAnnotation[]) annotations.toArray(new IAnnotation[annotations.size()]); >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileInfo.java >index bcf7ceb..e1714a0 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileInfo.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileInfo.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -107,12 +107,6 @@ > } > if ((tagBits & TagBits.AnnotationSafeVarargs) != 0) { > generateStandardAnnotation(javaElement, TypeConstants.JAVA_LANG_SAFEVARARGS, Annotation.NO_MEMBER_VALUE_PAIRS, newElements); >- } >- if ((tagBits & TagBits.AnnotationPostConstruct) != 0) { >- generateStandardAnnotation(javaElement, TypeConstants.JAVAX_ANNOTATION_POSTCONSTRUCT, Annotation.NO_MEMBER_VALUE_PAIRS, newElements); >- } >- if ((tagBits & TagBits.AnnotationPreDestroy) != 0) { >- generateStandardAnnotation(javaElement, TypeConstants.JAVAX_ANNOTATION_PREDESTROY, Annotation.NO_MEMBER_VALUE_PAIRS, newElements); > } > // note that JAVA_LANG_SUPPRESSWARNINGS and JAVA_LANG_OVERRIDE cannot appear in binaries > } >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileWorkingCopy.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileWorkingCopy.java >index d1027f2..4c085ce 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileWorkingCopy.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileWorkingCopy.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2008 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Stephan Herrmann - Contribution for Bug 337935 - Test failures when run as an IDE (org.eclipse.sdk.ide) > *******************************************************************************/ > package org.eclipse.jdt.internal.core; > >@@ -81,21 +82,18 @@ > protected IBuffer openBuffer(IProgressMonitor pm, Object info) throws JavaModelException { > > // create buffer >- IBuffer buffer = this.owner.createBuffer(this); >- if (buffer == null) return null; >+ IBuffer buffer = BufferManager.createBuffer(this); > > // set the buffer source >- if (buffer.getCharacters() == null) { >- IBuffer classFileBuffer = this.classFile.getBuffer(); >- if (classFileBuffer != null) { >- buffer.setContents(classFileBuffer.getCharacters()); >- } else { >- // Disassemble >- IClassFileReader reader = ToolFactory.createDefaultClassFileReader(this.classFile, IClassFileReader.ALL); >- Disassembler disassembler = new Disassembler(); >- String contents = disassembler.disassemble(reader, Util.getLineSeparator("", getJavaProject()), ClassFileBytesDisassembler.WORKING_COPY); //$NON-NLS-1$ >- buffer.setContents(contents); >- } >+ IBuffer classFileBuffer = this.classFile.getBuffer(); >+ if (classFileBuffer != null) { >+ buffer.setContents(classFileBuffer.getCharacters()); >+ } else { >+ // Disassemble >+ IClassFileReader reader = ToolFactory.createDefaultClassFileReader(this.classFile, IClassFileReader.ALL); >+ Disassembler disassembler = new Disassembler(); >+ String contents = disassembler.disassemble(reader, Util.getLineSeparator("", getJavaProject()), ClassFileBytesDisassembler.WORKING_COPY); //$NON-NLS-1$ >+ buffer.setContents(contents); > } > > // add buffer to buffer cache >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathChange.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathChange.java >index b96cd44..7a461df 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathChange.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathChange.java >@@ -10,6 +10,7 @@ > *******************************************************************************/ > package org.eclipse.jdt.internal.core; > >+import java.net.URL; > import java.util.ArrayList; > import java.util.HashMap; > import java.util.HashSet; >@@ -335,7 +336,7 @@ > boolean found = false; > for (int j = 0; j < accumulatedRoots.size(); j++) { > IPackageFragmentRoot root = (IPackageFragmentRoot) accumulatedRoots.elementAt(j); >- if (!root.getPath().equals(oldRoot.getPath())) { >+ if (root.getPath().equals(oldRoot.getPath())) { > found = true; > break; > } >@@ -511,7 +512,7 @@ > > for (int i = 0; i < newLength; i++) { > int index = classpathContains(this.oldResolvedClasspath, newResolvedClasspath[i]); >- if (index == -1) { >+ if (index == -1 || newResolvedClasspath[i].getEntryKind() == IClasspathEntry.CPE_LIBRARY) { > // remote projects are not indexed in this project > if (newResolvedClasspath[i].getEntryKind() == IClasspathEntry.CPE_PROJECT){ > continue; >@@ -519,6 +520,7 @@ > > // Request indexing > int entryKind = newResolvedClasspath[i].getEntryKind(); >+ URL newurl = ((ClasspathEntry)newResolvedClasspath[i]).getLibraryIndexLocation(); > switch (entryKind) { > case IClasspathEntry.CPE_LIBRARY: > boolean pathHasChanged = true; >@@ -526,12 +528,19 @@ > for (int j = 0; j < oldLength; j++) { > IClasspathEntry oldEntry = this.oldResolvedClasspath[j]; > if (oldEntry.getPath().equals(newPath)) { >- pathHasChanged = false; >+ URL oldurl = ((ClasspathEntry)oldEntry).getLibraryIndexLocation(); >+ if (oldurl == null && newurl == null) { >+ pathHasChanged = false; >+ } else if (oldurl != null && newurl != null) { >+ pathHasChanged = !(newurl.equals(oldurl)); >+ } else if (oldurl != null) { >+ indexManager.removeIndex(newPath); >+ } > break; > } > } > if (pathHasChanged) { >- indexManager.indexLibrary(newPath, this.project.getProject()); >+ indexManager.indexLibrary(newPath, this.project.getProject(), newurl); > } > break; > case IClasspathEntry.CPE_SOURCE: >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java >index d8086ff..8baef63 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Terry Parker <tparker@google.com> - DeltaProcessor misses state changes in archive files, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=357425 > *******************************************************************************/ > package org.eclipse.jdt.internal.core; > >@@ -16,6 +17,8 @@ > import java.io.InputStream; > import java.io.OutputStreamWriter; > import java.io.UnsupportedEncodingException; >+import java.net.MalformedURLException; >+import java.net.URL; > import java.util.ArrayList; > import java.util.HashMap; > import java.util.HashSet; >@@ -1268,6 +1271,15 @@ > return false; > } > >+ public String getSourceAttachmentEncoding() { >+ for (int i = 0, length = this.extraAttributes.length; i < length; i++) { >+ IClasspathAttribute attribute = this.extraAttributes[i]; >+ if (IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING.equals(attribute.getName())) >+ return attribute.getValue(); >+ } >+ return null; >+ } >+ > /** > * Returns the kind of a <code>PackageFragmentRoot</code> from its <code>String</code> form. > */ >@@ -1523,6 +1535,45 @@ > > return JavaCore.getResolvedClasspathEntry(this); > } >+ >+ /** >+ * This function computes the URL of the index location for this classpath entry. It returns null if the URL is >+ * invalid. >+ */ >+ public URL getLibraryIndexLocation() { >+ switch(getEntryKind()) { >+ case IClasspathEntry.CPE_LIBRARY : >+ case IClasspathEntry.CPE_VARIABLE : >+ break; >+ default : >+ return null; >+ } >+ if (this.extraAttributes == null) return null; >+ for (int i= 0; i < this.extraAttributes.length; i++) { >+ IClasspathAttribute attrib= this.extraAttributes[i]; >+ if (IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME.equals(attrib.getName())) { >+ String value = attrib.getValue(); >+ try { >+ return new URL(value); >+ } catch (MalformedURLException e) { >+ return null; >+ } >+ } >+ } >+ return null; >+ } >+ >+ public boolean ignoreOptionalProblems() { >+ if (this.entryKind == IClasspathEntry.CPE_SOURCE) { >+ for (int i = 0; i < this.extraAttributes.length; i++) { >+ IClasspathAttribute attrib = this.extraAttributes[i]; >+ if (IClasspathAttribute.IGNORE_OPTIONAL_PROBLEMS.equals(attrib.getName())) { >+ return "true".equals(attrib.getValue()); //$NON-NLS-1$ >+ } >+ } >+ } >+ return false; >+ } > > /** > * Validate a given classpath and output location for a project, using the following rules: >@@ -1776,6 +1827,7 @@ > // perform one separate iteration so as to not take precedence over previously checked scenarii (in particular should > // diagnose nesting source folder issue before this one, for example, [src]"Project/", [src]"Project/source/" and output="Project/" should > // first complain about missing exclusion pattern >+ IJavaModelStatus cachedStatus = null; > for (int i = 0 ; i < length; i++) { > IClasspathEntry entry = classpath[i]; > if (entry == null) continue; >@@ -1788,30 +1840,53 @@ > > if (kind == IClasspathEntry.CPE_SOURCE) { > IPath output = entry.getOutputLocation(); >- if (output == null) continue; // 36465 - for 2.0 backward compatibility, only check specific output locations (the default can still coincidate) >- // if (output == null) output = projectOutputLocation; // if no specific output, still need to check using default output (this line would check default output) >+ if (output == null) output = projectOutputLocation; // if no specific output, still need to check using default output (this line would check default output) > for (int j = 0; j < length; j++) { > IClasspathEntry otherEntry = classpath[j]; > if (otherEntry == entry) continue; > >- // Build some common strings for status message >- boolean opStartsWithProject = projectName.equals(otherEntry.getPath().segment(0)); >- String otherPathMsg = opStartsWithProject ? otherEntry.getPath().removeFirstSegments(1).toString() : otherEntry.getPath().makeRelative().toString(); >- > switch (otherEntry.getEntryKind()) { > case IClasspathEntry.CPE_SOURCE : >- if (otherEntry.getPath().equals(output)) { >- return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_cannotUseDistinctSourceFolderAsOutput, new String[] {entryPathMsg, otherPathMsg, projectName})); >+ // Bug 287164 : Report errors of overlapping output locations only if the user sets the corresponding preference. >+ // The check is required for backward compatibility with bug-fix 36465. >+ String option = javaProject.getOption(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, true); >+ if (otherEntry.getPath().equals(output) >+ && !JavaCore.IGNORE.equals(option)) { >+ boolean opStartsWithProject = projectName.equals(otherEntry.getPath().segment(0)); >+ String otherPathMsg = opStartsWithProject ? otherEntry.getPath().removeFirstSegments(1).toString() : otherEntry.getPath().makeRelative().toString(); >+ if (JavaCore.ERROR.equals(option)) { >+ return new JavaModelStatus(IStatus.ERROR, IJavaModelStatusConstants.OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, >+ Messages.bind(Messages.classpath_cannotUseDistinctSourceFolderAsOutput, new String[] { >+ entryPathMsg, otherPathMsg, projectName })); >+ } >+ if (cachedStatus == null) { >+ // Note that the isOK() is being overridden to return true. This is an exceptional scenario >+ cachedStatus = new JavaModelStatus(IStatus.OK, IJavaModelStatusConstants.OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, >+ Messages.bind(Messages.classpath_cannotUseDistinctSourceFolderAsOutput, new String[] { >+ entryPathMsg, otherPathMsg, projectName })){ >+ public boolean isOK() { >+ return true; >+ } >+ }; >+ } > } > break; > case IClasspathEntry.CPE_LIBRARY : >- if (otherEntry.getPath().equals(output)) { >+ if (output != projectOutputLocation && otherEntry.getPath().equals(output)) { >+ boolean opStartsWithProject = projectName.equals(otherEntry.getPath().segment(0)); >+ String otherPathMsg = opStartsWithProject ? otherEntry.getPath().removeFirstSegments(1).toString() : otherEntry.getPath().makeRelative().toString(); > return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_cannotUseLibraryAsOutput, new String[] {entryPathMsg, otherPathMsg, projectName})); > } > } > } > } > } >+ >+ // NOTE: The above code that checks for IJavaModelStatusConstants.OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, can be configured to return >+ // a WARNING status and hence should be at the end of this validation method. Any other code that might return a more severe ERROR should be >+ // inserted before the mentioned code. >+ if (cachedStatus != null) return cachedStatus; >+ > return JavaModelStatus.VERIFIED_OK; > } > >@@ -1827,6 +1902,9 @@ > * @return a java model status describing the problem related to this classpath entry if any, a status object with code <code>IStatus.OK</code> if the entry is fine > */ > public static IJavaModelStatus validateClasspathEntry(IJavaProject project, IClasspathEntry entry, boolean checkSourceAttachment, boolean referredByContainer){ >+ if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) { >+ JavaModelManager.getJavaModelManager().removeFromInvalidArchiveCache(entry.getPath()); >+ } > IJavaModelStatus status = validateClasspathEntry(project, entry, null, checkSourceAttachment, referredByContainer); > // https://bugs.eclipse.org/bugs/show_bug.cgi?id=171136 and https://bugs.eclipse.org/bugs/show_bug.cgi?id=300136 > // Ignore class path errors from optional entries. >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathValidation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathValidation.java >index ea310a3..345535a 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathValidation.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathValidation.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -12,6 +12,7 @@ > > import org.eclipse.core.resources.IProject; > import org.eclipse.core.runtime.IPath; >+import org.eclipse.core.runtime.IStatus; > import org.eclipse.jdt.core.IClasspathEntry; > import org.eclipse.jdt.core.IJavaModelStatus; > import org.eclipse.jdt.core.JavaModelException; >@@ -37,7 +38,7 @@ > // project doesn't exist > IProject resource = this.project.getProject(); > if (resource.isAccessible()) { >- this.project.flushClasspathProblemMarkers(true/*flush cycle markers*/, true/*flush classpath format markers*/); >+ this.project.flushClasspathProblemMarkers(true/*flush cycle markers*/, true/*flush classpath format markers*/, true /*flush overlapping output markers*/); > > // remove problems and tasks created by the builder > JavaBuilder.removeProblemsAndTasksFor(resource); >@@ -56,12 +57,15 @@ > } > > // update classpath format problems >- this.project.flushClasspathProblemMarkers(false/*cycle*/, true/*format*/); >+ this.project.flushClasspathProblemMarkers(false/*cycle*/, true/*format*/, false/*overlapping*/); > if (!status.isOK()) > this.project.createClasspathProblemMarker(status); > >+ // update overlapping output problem markers >+ this.project.flushClasspathProblemMarkers(false/*cycle*/, false/*format*/, true/*overlapping*/); >+ > // update resolved classpath problems >- this.project.flushClasspathProblemMarkers(false/*cycle*/, false/*format*/); >+ this.project.flushClasspathProblemMarkers(false/*cycle*/, false/*format*/, false/*overlapping*/); > > if (rawClasspath != JavaProject.INVALID_CLASSPATH && outputLocation != null) { > for (int i = 0; i < rawClasspath.length; i++) { >@@ -71,7 +75,7 @@ > } > } > status = ClasspathEntry.validateClasspath(this.project, rawClasspath, outputLocation); >- if (!status.isOK()) >+ if (status.getCode() != IStatus.OK) > this.project.createClasspathProblemMarker(status); > } > } >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java >index ae648ae..332762c 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -1005,6 +1005,9 @@ > if (resource == null) return false; > return ((CompilationUnitElementInfo)info).timestamp != resource.getModificationStamp(); > } >+public boolean ignoreOptionalProblems() { >+ return getPackageFragmentRoot().ignoreOptionalProblems(); >+} > /** > * @see IWorkingCopy#isBasedOn(IResource) > * @deprecated >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitProblemFinder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitProblemFinder.java >index 1374a3f..a4891ca 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitProblemFinder.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitProblemFinder.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -91,8 +91,9 @@ > */ > public void accept(ISourceType[] sourceTypes, PackageBinding packageBinding, AccessRestriction accessRestriction) { > // ensure to jump back to toplevel type for first one (could be a member) >-// while (sourceTypes[0].getEnclosingType() != null) >-// sourceTypes[0] = sourceTypes[0].getEnclosingType(); >+ while (sourceTypes[0].getEnclosingType() != null) { >+ sourceTypes[0] = sourceTypes[0].getEnclosingType(); >+ } > > CompilationResult result = > new CompilationResult(sourceTypes[0].getFileName(), 1, 1, this.options.maxProblemsPerUnit); >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitStructureRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitStructureRequestor.java >index 50a0c9d..0312971 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitStructureRequestor.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitStructureRequestor.java >@@ -81,6 +81,12 @@ > */ > private HashtableOfObjectToInt occurenceCounts; > >+ /* >+ * A table to store the occurrence count of anonymous types. The key will be the handle to the >+ * enclosing type of the anonymous. >+ */ >+ private HashtableOfObjectToInt localOccurrenceCounts; >+ > /** > * Stack of parent scope info objects. The info on the > * top of the stack is the parent of the next element found. >@@ -128,6 +134,7 @@ > this.unitInfo = unitInfo; > this.newElements = newElements; > this.occurenceCounts = new HashtableOfObjectToInt(); >+ this.localOccurrenceCounts = new HashtableOfObjectToInt(5); > } > /** > * @see ISourceElementRequestor >@@ -707,6 +714,20 @@ > this.occurenceCounts.put(handle, ++occurenceCount); > handle.occurrenceCount = occurenceCount; > } >+ >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=342393 >+ // For anonymous source types, the occurrence count should be in the context >+ // of the enclosing type. >+ if (handle instanceof SourceType && handle.getElementName().length() == 0) { >+ Object key = handle.getParent().getAncestor(IJavaElement.TYPE); >+ occurenceCount = this.localOccurrenceCounts.get(key); >+ if (occurenceCount == -1) >+ this.localOccurrenceCounts.put(key, 1); >+ else { >+ this.localOccurrenceCounts.put(key, ++occurenceCount); >+ ((SourceType)handle).localOccurrenceCount = occurenceCount; >+ } >+ } > } > protected IMemberValuePair getMemberValuePair(MemberValuePair memberValuePair) { > String memberName = new String(memberValuePair.name); >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyResourceElementsOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyResourceElementsOperation.java >index 291378c..426d41e 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyResourceElementsOperation.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyResourceElementsOperation.java >@@ -266,20 +266,29 @@ > * <li>On a copy, the delta should be rooted in the dest project > * <li>On a move, two deltas are generated<ul> > * <li>one rooted in the source project >- * <li>one rooted in the destination project</ul></ul> >+ * <li>one rooted in the destination project >+ * <li> When a CU is being overwritten, the delta on the destination will be of type F_CONTENT </ul></ul> > * If the operation is rooted in a single project, the delta is rooted in that project > * > */ >- protected void prepareDeltas(IJavaElement sourceElement, IJavaElement destinationElement, boolean isMove) { >+ protected void prepareDeltas(IJavaElement sourceElement, IJavaElement destinationElement, boolean isMove, boolean overWriteCU) { > if (Util.isExcluded(sourceElement) || Util.isExcluded(destinationElement)) return; >+ > IJavaProject destProject = destinationElement.getJavaProject(); > if (isMove) { > IJavaProject sourceProject = sourceElement.getJavaProject(); > getDeltaFor(sourceProject).movedFrom(sourceElement, destinationElement); >- getDeltaFor(destProject).movedTo(destinationElement, sourceElement); >+ if (!overWriteCU) { >+ getDeltaFor(destProject).movedTo(destinationElement, sourceElement); >+ return; >+ } > } else { >- getDeltaFor(destProject).added(destinationElement); >+ if (!overWriteCU) { >+ getDeltaFor(destProject).added(destinationElement); >+ return; >+ } > } >+ getDeltaFor(destinationElement.getJavaProject()).changed(destinationElement, IJavaElementDelta.F_CONTENT); > } > /** > * Copies/moves a compilation unit with the name <code>newCUName</code> >@@ -357,12 +366,14 @@ > } > > // register the correct change deltas >- prepareDeltas(source, destCU, isMove()); >+ boolean contentChanged = this.force && destFile.exists(); >+ prepareDeltas(source, destCU, isMove(), contentChanged); >+ > if (newCUName != null) { > //the main type has been renamed > String oldName = Util.getNameWithoutJavaLikeExtension(source.getElementName()); > String newName = Util.getNameWithoutJavaLikeExtension(newCUName); >- prepareDeltas(source.getType(oldName), destCU.getType(newName), isMove()); >+ prepareDeltas(source.getType(oldName), destCU.getType(newName), isMove(), false); > } > } else { > if (!this.force) { >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java >index b15d3c8..c36e288 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java >@@ -7,10 +7,13 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Terry Parker <tparker@google.com> - DeltaProcessor exhibits O(N^2) behavior, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=354332 >+ * Terry Parker <tparker@google.com> - DeltaProcessor misses state changes in archive files, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=357425 > *******************************************************************************/ > package org.eclipse.jdt.internal.core; > > import java.io.File; >+import java.net.URL; > import java.util.*; > > import org.eclipse.core.resources.IContainer; >@@ -953,6 +956,7 @@ > // project does not exist -> ignore > continue; > } >+ boolean deltaContainsModifiedJar = false; > for (int j = 0; j < entries.length; j++){ > if (entries[j].getEntryKind() == IClasspathEntry.CPE_LIBRARY) { > IPath entryPath = entries[j].getPath(); >@@ -994,8 +998,12 @@ > // first remove the index so that it is forced to be re-indexed > this.manager.indexManager.removeIndex(entryPath); > // then index the jar >- this.manager.indexManager.indexLibrary(entryPath, project.getProject()); >+ this.manager.indexManager.indexLibrary(entryPath, project.getProject(), ((ClasspathEntry)entries[j]).getLibraryIndexLocation()); > } else { >+ URL indexLocation = ((ClasspathEntry)entries[j]).getLibraryIndexLocation(); >+ if (indexLocation != null) { // force reindexing, this could be faster rather than maintaining the list >+ this.manager.indexManager.indexLibrary(entryPath, project.getProject(), indexLocation); >+ } > externalArchivesStatus.put(entryPath, EXTERNAL_JAR_UNCHANGED); > } > } else { >@@ -1006,7 +1014,7 @@ > this.state.getExternalLibTimeStamps().put(entryPath, new Long(newTimeStamp)); > // index the new jar > this.manager.indexManager.removeIndex(entryPath); >- this.manager.indexManager.indexLibrary(entryPath, project.getProject()); >+ this.manager.indexManager.indexLibrary(entryPath, project.getProject(), ((ClasspathEntry)entries[j]).getLibraryIndexLocation()); > } > } > } else { // internal JAR >@@ -1022,7 +1030,7 @@ > System.out.println("- External JAR ADDED, affecting root: "+root.getElementName()); //$NON-NLS-1$ > } > elementAdded(root, null, null); >- javaProject.resetResolvedClasspath(); // in case it contains a chained jar >+ deltaContainsModifiedJar = true; > this.state.addClasspathValidation(javaProject); // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=185733 > hasDelta = true; > } else if (status == EXTERNAL_JAR_CHANGED) { >@@ -1031,7 +1039,7 @@ > System.out.println("- External JAR CHANGED, affecting root: "+root.getElementName()); //$NON-NLS-1$ > } > contentChanged(root); >- javaProject.resetResolvedClasspath(); // in case it contains a chained jar >+ deltaContainsModifiedJar = true; > hasDelta = true; > } else if (status == EXTERNAL_JAR_REMOVED) { > PackageFragmentRoot root = (PackageFragmentRoot) javaProject.getPackageFragmentRoot(entryPath.toString()); >@@ -1039,12 +1047,16 @@ > System.out.println("- External JAR REMOVED, affecting root: "+root.getElementName()); //$NON-NLS-1$ > } > elementRemoved(root, null, null); >- javaProject.resetResolvedClasspath(); // in case it contains a chained jar >+ deltaContainsModifiedJar = true; > this.state.addClasspathValidation(javaProject); // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=185733 > hasDelta = true; > } > } > } >+ } >+ >+ if (deltaContainsModifiedJar) { >+ javaProject.resetResolvedClasspath(); > } > } > // ensure the external file cache is reset so that if a .jar file is deleted but no longer on the classpath, it won't appear as changed next time it is added >@@ -2622,13 +2634,13 @@ > switch (delta.getKind()) { > case IResourceDelta.ADDED: > // index the new jar >- indexManager.indexLibrary(jarPath, root.getJavaProject().getProject()); >+ indexManager.indexLibrary(jarPath, root.getJavaProject().getProject(), root.getIndexPath()); > break; > case IResourceDelta.CHANGED: > // first remove the index so that it is forced to be re-indexed > indexManager.removeIndex(jarPath); > // then index the jar >- indexManager.indexLibrary(jarPath, root.getJavaProject().getProject()); >+ indexManager.indexLibrary(jarPath, root.getJavaProject().getProject(), root.getIndexPath()); > break; > case IResourceDelta.REMOVED: > // the jar was physically removed: remove the index >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ExternalFoldersManager.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ExternalFoldersManager.java >index d615698..928b6d1 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ExternalFoldersManager.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ExternalFoldersManager.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -122,7 +122,7 @@ > } while (result.exists()); > if (scheduleForCreation) { > if (this.pendingFolders == null) >- this.pendingFolders = new HashSet(); >+ this.pendingFolders = Collections.synchronizedSet(new HashSet()); > this.pendingFolders.add(externalFolderPath); > } > knownFolders.put(externalFolderPath, result); >@@ -166,16 +166,22 @@ > catch(CoreException e) { > throw new JavaModelException(e); > } >- Iterator iterator = this.pendingFolders.iterator(); >- while (iterator.hasNext()) { >- Object folderPath = iterator.next(); >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=368152 >+ // To avoid race condition (from addFolder and removeFolder, load the map elements into an array and clear the map immediately. >+ // The createLinkFolder being in the synchronized block can cause a deadlock and hence keep it out of the synchronized block. >+ Object[] arrayOfFolders = null; >+ synchronized (this.pendingFolders) { >+ arrayOfFolders = this.pendingFolders.toArray(); >+ this.pendingFolders.clear(); >+ } >+ >+ for (int i=0; i < arrayOfFolders.length; i++) { > try { >- createLinkFolder((IPath) folderPath, false, externalFoldersProject, monitor); >+ createLinkFolder((IPath) arrayOfFolders[i], false, externalFoldersProject, monitor); > } catch (CoreException e) { >- Util.log(e, "Error while creating a link for external folder :" + folderPath); //$NON-NLS-1$ >+ Util.log(e, "Error while creating a link for external folder :" + arrayOfFolders[i]); //$NON-NLS-1$ > } > } >- this.pendingFolders.clear(); > } > > public void cleanUp(IProgressMonitor monitor) throws CoreException { >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java >index 5b18c19..3cd4d07 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java >@@ -10,6 +10,7 @@ > *******************************************************************************/ > package org.eclipse.jdt.internal.core; > >+import java.net.URL; > import java.util.*; > import java.util.zip.ZipEntry; > import java.util.zip.ZipException; >@@ -292,4 +293,15 @@ > return; > super.toStringAncestors(buffer); > } >+ >+ public URL getIndexPath() { >+ try { >+ IClasspathEntry entry = ((JavaProject) getParent()).getClasspathEntryFor(getPath()); >+ if (entry != null) return ((ClasspathEntry)entry).getLibraryIndexLocation(); >+ } catch (JavaModelException e) { >+ // ignore exception >+ } >+ return null; >+ } >+ > } >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java >index 532ed94..91c6dde 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java >@@ -58,6 +58,7 @@ > defaultOptionsMap.put(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL, JavaCore.IGNORE); > defaultOptionsMap.put(JavaCore.CORE_ENABLE_CLASSPATH_EXCLUSION_PATTERNS, JavaCore.ENABLED); > defaultOptionsMap.put(JavaCore.CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS, JavaCore.ENABLED); >+ defaultOptionsMap.put(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, JavaCore.ERROR); > > // encoding setting comes from resource plug-in > optionNames.add(JavaCore.CORE_ENCODING); >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelCache.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelCache.java >index 6a049a9..eb4297c 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelCache.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelCache.java >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Terry Parker <tparker@google.com> (Google Inc.) https://bugs.eclipse.org/365499 > *******************************************************************************/ > package org.eclipse.jdt.internal.core; > import java.util.HashMap; >@@ -28,6 +29,7 @@ > public static final int DEFAULT_OPENABLE_SIZE = 250; // average 6629 bytes per openable (includes children) -> maximum size : 662900*BASE_VALUE bytes > public static final int DEFAULT_CHILDREN_SIZE = 250*20; // average 20 children per openable > public static final String RATIO_PROPERTY = "org.eclipse.jdt.core.javamodelcache.ratio"; //$NON-NLS-1$ >+ public static final String JAR_TYPE_RATIO_PROPERTY = "org.eclipse.jdt.core.javamodelcache.jartyperatio"; //$NON-NLS-1$ > > public static final Object NON_EXISTING_JAR_TYPE_INFO = new Object(); > >@@ -72,9 +74,9 @@ > protected LRUCache jarTypeCache; > > public JavaModelCache() { >- // set the size of the caches in function of the maximum amount of memory available >+ // set the size of the caches as a function of the maximum amount of memory available > double ratio = getMemoryRatio(); >- // adjust the size of the openable cache in function of the RATIO_PROPERTY property >+ // adjust the size of the openable cache using the RATIO_PROPERTY property > double openableRatio = getOpenableRatio(); > this.projectCache = new HashMap(DEFAULT_PROJECT_SIZE); // NB: Don't use a LRUCache for projects as they are constantly reopened (e.g. during delta processing) > if (VERBOSE) { >@@ -91,13 +93,21 @@ > } > > private double getOpenableRatio() { >- String property = System.getProperty(RATIO_PROPERTY); >+ return getRatioForProperty(RATIO_PROPERTY); >+} >+ >+private double getJarTypeRatio() { >+ return getRatioForProperty(JAR_TYPE_RATIO_PROPERTY); >+} >+ >+private double getRatioForProperty(String propertyName) { >+ String property = System.getProperty(propertyName); > if (property != null) { > try { > return Double.parseDouble(property); > } catch (NumberFormatException e) { > // ignore >- Util.log(e, "Could not parse value for " + RATIO_PROPERTY + ": " + property); //$NON-NLS-1$ //$NON-NLS-2$ >+ Util.log(e, "Could not parse value for " + propertyName + ": " + property); //$NON-NLS-1$ //$NON-NLS-2$ > } > } > return 1.0; >@@ -249,7 +259,7 @@ > } > } > protected void resetJarTypeCache() { >- this.jarTypeCache = new LRUCache((int) (DEFAULT_OPENABLE_SIZE * getMemoryRatio())); >+ this.jarTypeCache = new LRUCache((int) (DEFAULT_OPENABLE_SIZE * getMemoryRatio() * getJarTypeRatio())); > } > public String toString() { > return toStringFillingRation(""); //$NON-NLS-1$ >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java >index cdead40..955e856 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -11,6 +11,7 @@ > * before its contents > * (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=102422) > * Stephan Herrmann - Contribution for Bug 346010 - [model] strange initialization dependency in OptionTests >+ * Terry Parker <tparker@google.com> - DeltaProcessor misses state changes in archive files, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=357425 > *******************************************************************************/ > package org.eclipse.jdt.internal.core; > >@@ -1412,9 +1413,7 @@ > public static boolean CP_RESOLVE_VERBOSE_ADVANCED = false; > public static boolean CP_RESOLVE_VERBOSE_FAILURE = false; > public static boolean ZIP_ACCESS_VERBOSE = false; >- // temporary debug flag to track failures of bug 302850 >- public static boolean DEBUG_302850 = false; >- >+ > /** > * A cache of opened zip files per thread. > * (for a given thread, the object value is a HashMap from IPath to java.io.ZipFile) >@@ -1481,7 +1480,8 @@ > propertyName.equals(JavaCore.CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS) || > propertyName.equals(JavaCore.CORE_INCOMPLETE_CLASSPATH) || > propertyName.equals(JavaCore.CORE_CIRCULAR_CLASSPATH) || >- propertyName.equals(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL)) { >+ propertyName.equals(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL) || >+ propertyName.equals(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE)) { > JavaModelManager manager = JavaModelManager.getJavaModelManager(); > IJavaModel model = manager.getJavaModel(); > IJavaProject[] projects; >@@ -2153,13 +2153,10 @@ > // return cached options if already computed > Hashtable cachedOptions; // use a local variable to avoid race condition (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=256329 ) > if ((cachedOptions = this.optionsCache) != null) { >- if (DEBUG_302850) checkTaskTags("Retrieving options from optionsCache", this.optionsCache); //$NON-NLS-1$ > return new Hashtable(cachedOptions); > } >- if (DEBUG_302850) System.out.println("optionsCache was null"); //$NON-NLS-1$ > if (!Platform.isRunning()) { > this.optionsCache = getDefaultOptionsNoInitialization(); >- if (DEBUG_302850) checkTaskTags("Platform is not running", this.optionsCache); //$NON-NLS-1$ > return new Hashtable(this.optionsCache); > } > // init >@@ -2175,7 +2172,6 @@ > options.put(propertyName, propertyValue); > } > } >- if (DEBUG_302850) checkTaskTags("Options initialized from preferences", options); //$NON-NLS-1$ > > // set deprecated options using preferences service lookup > Iterator deprecatedEntries = this.deprecatedOptions.entrySet().iterator(); >@@ -2201,28 +2197,10 @@ > addDeprecatedOptions(options); > > Util.fixTaskTags(options); >- if (DEBUG_302850) checkTaskTags("Retrieved options from preferences", options); //$NON-NLS-1$ > // store built map in cache > this.optionsCache = new Hashtable(options); >- if (DEBUG_302850) checkTaskTags("Stored optionsCache", this.optionsCache); //$NON-NLS-1$ >- > // return built map > return options; >- } >- >- // debugging bug 302850: >- private void checkTaskTags(String msg, Hashtable someOptions) { >- System.out.println(msg); >- Object taskTags = someOptions.get(JavaCore.COMPILER_TASK_TAGS); >- System.out.println(" + Task tags: " + taskTags); //$NON-NLS-1$ >- if (taskTags == null || "".equals(taskTags)) { //$NON-NLS-1$ >- System.out.println(" - option names: "+this.optionNames); //$NON-NLS-1$ >- System.out.println(" - Call stack:"); //$NON-NLS-1$ >- StackTraceElement[] elements = new Exception().getStackTrace(); >- for (int i=0,n=elements.length; i<n; i++) { >- System.out.println(" + "+elements[i]); //$NON-NLS-1$ >- } >- } > } > > // Do not modify without modifying getDefaultOptions() >@@ -2248,7 +2226,8 @@ > defaultOptionsMap.put(JavaCore.CORE_JAVA_BUILD_ORDER, JavaCore.IGNORE); > defaultOptionsMap.put(JavaCore.CORE_INCOMPLETE_CLASSPATH, JavaCore.ERROR); > defaultOptionsMap.put(JavaCore.CORE_CIRCULAR_CLASSPATH, JavaCore.ERROR); >- defaultOptionsMap.put(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL, JavaCore.IGNORE); >+ defaultOptionsMap.put(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL, JavaCore.IGNORE); >+ defaultOptionsMap.put(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, JavaCore.ERROR); > defaultOptionsMap.put(JavaCore.CORE_ENABLE_CLASSPATH_EXCLUSION_PATTERNS, JavaCore.ENABLED); > defaultOptionsMap.put(JavaCore.CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS, JavaCore.ENABLED); > >@@ -3084,6 +3063,12 @@ > > public boolean isInvalidArchive(IPath path) { > return this.invalidArchives != null && this.invalidArchives.contains(path); >+ } >+ >+ public void removeFromInvalidArchiveCache(IPath path) { >+ if (this.invalidArchives != null) { >+ this.invalidArchives.remove(path); >+ } > } > > public void setClasspathBeingResolved(IJavaProject project, boolean classpathIsResolved) { >@@ -4827,57 +4812,46 @@ > } > > public void setOptions(Hashtable newOptions) { >- >- if (DEBUG_302850) { >- System.out.println("Entering in JavaModelManager.setOptions():"); //$NON-NLS-1$ >- System.out.println(new CompilerOptions(newOptions).toString()); >- System.out.println(" - Call stack:"); //$NON-NLS-1$ >- StackTraceElement[] elements = new Exception().getStackTrace(); >- for (int i=0,n=elements.length; i<n; i++) { >- System.out.println(" + "+elements[i]); //$NON-NLS-1$ >+ Hashtable cachedValue = newOptions == null ? null : new Hashtable(newOptions); >+ IEclipsePreferences defaultPreferences = getDefaultPreferences(); >+ IEclipsePreferences instancePreferences = getInstancePreferences(); >+ >+ if (newOptions == null){ >+ try { >+ instancePreferences.clear(); >+ } catch(BackingStoreException e) { >+ // ignore >+ } >+ } else { >+ Enumeration keys = newOptions.keys(); >+ while (keys.hasMoreElements()){ >+ String key = (String)keys.nextElement(); >+ int optionLevel = getOptionLevel(key); >+ if (optionLevel == UNKNOWN_OPTION) continue; // unrecognized option >+ if (key.equals(JavaCore.CORE_ENCODING)) { >+ if (cachedValue != null) { >+ cachedValue.put(key, JavaCore.getEncoding()); >+ } >+ continue; // skipped, contributed by resource prefs >+ } >+ String value = (String) newOptions.get(key); >+ String defaultValue = defaultPreferences.get(key, null); >+ // Store value in preferences >+ if (defaultValue != null && defaultValue.equals(value)) { >+ value = null; >+ } >+ storePreference(key, value, instancePreferences, newOptions); >+ } >+ try { >+ // persist options >+ instancePreferences.flush(); >+ } catch(BackingStoreException e) { >+ // ignore > } > } >- >- Hashtable cachedValue = newOptions == null ? null : new Hashtable(newOptions); >- IEclipsePreferences defaultPreferences = getDefaultPreferences(); >- IEclipsePreferences instancePreferences = getInstancePreferences(); >- >- if (newOptions == null){ >- try { >- instancePreferences.clear(); >- } catch(BackingStoreException e) { >- // ignore >- } >- } else { >- Enumeration keys = newOptions.keys(); >- while (keys.hasMoreElements()){ >- String key = (String)keys.nextElement(); >- int optionLevel = getOptionLevel(key); >- if (optionLevel == UNKNOWN_OPTION) continue; // unrecognized option >- if (key.equals(JavaCore.CORE_ENCODING)) { >- if (cachedValue != null) { >- cachedValue.put(key, JavaCore.getEncoding()); >- } >- continue; // skipped, contributed by resource prefs >- } >- String value = (String) newOptions.get(key); >- String defaultValue = defaultPreferences.get(key, null); >- // Store value in preferences >- if (defaultValue != null && defaultValue.equals(value)) { >- value = null; >- } >- storePreference(key, value, instancePreferences, newOptions); >- } >- try { >- // persist options >- instancePreferences.flush(); >- } catch(BackingStoreException e) { >- // ignore >- } >- } >- // update cache >- Util.fixTaskTags(cachedValue); >- this.optionsCache = cachedValue; >+ // update cache >+ Util.fixTaskTags(cachedValue); >+ this.optionsCache = cachedValue; > } > > public void startup() throws CoreException { >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java >index 42b1890..c78c697 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -433,7 +433,7 @@ > new JavaModelStatus(IJavaModelStatusConstants.CLASSPATH_CYCLE, project, cycleString)); > } > } else { >- project.flushClasspathProblemMarkers(true, false); >+ project.flushClasspathProblemMarkers(true, false, false); > } > } > } >@@ -803,7 +803,7 @@ > IMarker marker = null; > int severity; > String[] arguments = CharOperation.NO_STRINGS; >- boolean isCycleProblem = false, isClasspathFileFormatProblem = false; >+ boolean isCycleProblem = false, isClasspathFileFormatProblem = false, isOutputOverlapping = false; > switch (status.getCode()) { > > case IJavaModelStatusConstants.CLASSPATH_CYCLE : >@@ -830,7 +830,17 @@ > return; // setting == IGNORE > } > break; >- >+ case IJavaModelStatusConstants.OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE : >+ isOutputOverlapping = true; >+ setting = getOption(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, true); >+ if (JavaCore.ERROR.equals(setting)) { >+ severity = IMarker.SEVERITY_ERROR; >+ } else if (JavaCore.WARNING.equals(setting)) { >+ severity = IMarker.SEVERITY_WARNING; >+ } else { >+ return; // setting == IGNORE >+ } >+ break; > default: > IPath path = status.getPath(); > if (path != null) arguments = new String[] { path.toString() }; >@@ -852,6 +862,7 @@ > IMarker.LOCATION, > IJavaModelMarker.CYCLE_DETECTED, > IJavaModelMarker.CLASSPATH_FILE_FORMAT, >+ IJavaModelMarker.OUTPUT_OVERLAPPING_SOURCE, > IJavaModelMarker.ID, > IJavaModelMarker.ARGUMENTS , > IJavaModelMarker.CATEGORY_ID, >@@ -863,6 +874,7 @@ > Messages.classpath_buildPath, > isCycleProblem ? "true" : "false",//$NON-NLS-1$ //$NON-NLS-2$ > isClasspathFileFormatProblem ? "true" : "false",//$NON-NLS-1$ //$NON-NLS-2$ >+ isOutputOverlapping ? "true" : "false", //$NON-NLS-1$ //$NON-NLS-2$ > new Integer(status.getCode()), > Util.getProblemArgumentsForMarker(arguments) , > new Integer(CategorizedProblem.CAT_BUILDPATH), >@@ -1356,18 +1368,20 @@ > /** > * Remove all markers denoting classpath problems > */ //TODO (philippe) should improve to use a bitmask instead of booleans (CYCLE, FORMAT, VALID) >- protected void flushClasspathProblemMarkers(boolean flushCycleMarkers, boolean flushClasspathFormatMarkers) { >+ protected void flushClasspathProblemMarkers(boolean flushCycleMarkers, boolean flushClasspathFormatMarkers, boolean flushOverlappingOutputMarkers) { > try { > if (this.project.isAccessible()) { > IMarker[] markers = this.project.findMarkers(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO); > for (int i = 0, length = markers.length; i < length; i++) { > IMarker marker = markers[i]; >- if (flushCycleMarkers && flushClasspathFormatMarkers) { >+ if (flushCycleMarkers && flushClasspathFormatMarkers && flushOverlappingOutputMarkers) { > marker.delete(); > } else { > String cycleAttr = (String)marker.getAttribute(IJavaModelMarker.CYCLE_DETECTED); > String classpathFileFormatAttr = (String)marker.getAttribute(IJavaModelMarker.CLASSPATH_FILE_FORMAT); >+ String overlappingOutputAttr = (String) marker.getAttribute(IJavaModelMarker.OUTPUT_OVERLAPPING_SOURCE); > if ((flushCycleMarkers == (cycleAttr != null && cycleAttr.equals("true"))) //$NON-NLS-1$ >+ && (flushOverlappingOutputMarkers == (overlappingOutputAttr != null && overlappingOutputAttr.equals("true"))) //$NON-NLS-1$ > && (flushClasspathFormatMarkers == (classpathFileFormatAttr != null && classpathFileFormatAttr.equals("true")))){ //$NON-NLS-1$ > marker.delete(); > } >@@ -1513,6 +1527,7 @@ > propertyName.equals(JavaCore.CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS) || > propertyName.equals(JavaCore.CORE_INCOMPLETE_CLASSPATH) || > propertyName.equals(JavaCore.CORE_CIRCULAR_CLASSPATH) || >+ propertyName.equals(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE) || > propertyName.equals(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL)) > { > manager.deltaState.addClasspathValidation(JavaProject.this); >@@ -3104,8 +3119,8 @@ > * Note that it is orthogonal to IResource persistent properties, and client code has to decide > * which form of storage to use appropriately. Shared properties produce real resource files which > * can be shared through a VCM onto a server. Persistent properties are not shareable. >- * >- * shared properties end up in resource files, and thus cannot be modified during >+ * <p> >+ * Shared properties end up in resource files, and thus cannot be modified during > * delta notifications (a CoreException would then be thrown). > * > * @param key String >@@ -3129,7 +3144,7 @@ > if (rscFile.exists()) { > if (rscFile.isReadOnly()) { > // provide opportunity to checkout read-only .classpath file (23984) >- ResourcesPlugin.getWorkspace().validateEdit(new IFile[]{rscFile}, null); >+ ResourcesPlugin.getWorkspace().validateEdit(new IFile[]{rscFile}, IWorkspace.VALIDATE_PROMPT); > } > rscFile.setContents(inputStream, IResource.FORCE, null); > } else { >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavadocContents.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavadocContents.java >index e655477..f98325a 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavadocContents.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavadocContents.java >@@ -378,13 +378,8 @@ > } > IType declaringType = this.type; > if (declaringType.isMember()) { >- int depth = 0; > // might need to remove a part of the signature corresponding to the synthetic argument (only for constructor) > if (method.isConstructor() && !Flags.isStatic(declaringType.getFlags())) { >- depth++; >- } >- if (depth != 0) { >- // depth is 1 > int indexOfOpeningParen = anchor.indexOf('('); > if (indexOfOpeningParen == -1) { > // should not happen as this is a method signature >@@ -395,8 +390,11 @@ > int indexOfComma = anchor.indexOf(',', index); > if (indexOfComma != -1) { > index = indexOfComma + 2; >- anchor = anchor.substring(0, indexOfOpeningParen) + anchor.substring(index); >+ } else { >+ // no argument, but a synthetic argument >+ index = anchor.indexOf(')', index); > } >+ anchor = anchor.substring(0, indexOfOpeningParen) + anchor.substring(index); > } > } > return anchor + JavadocConstants.ANCHOR_PREFIX_END; >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java >index 59c69ce..d08dff5 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java >@@ -987,6 +987,13 @@ > break; > case IPackageFragmentRoot.K_SOURCE : > seekTypesInSourcePackage(matchName, pkg, firstDot, partialMatch, topLevelTypeName, acceptFlags, requestor); >+ if (matchName.indexOf('$') != -1) { >+ matchName= matchName.replace('$', '.'); >+ firstDot = matchName.indexOf('.'); >+ if (!partialMatch) >+ topLevelTypeName = firstDot == -1 ? matchName : matchName.substring(0, firstDot); >+ seekTypesInSourcePackage(matchName, pkg, firstDot, partialMatch, topLevelTypeName, acceptFlags, requestor); >+ } > break; > default : > return; >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NamedMember.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NamedMember.java >index 317b9e7..c966d1d 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NamedMember.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NamedMember.java >@@ -226,14 +226,22 @@ > } > StringBuffer buffer = new StringBuffer(declaringType.getTypeQualifiedName(enclosingTypeSeparator, showParameters)); > buffer.append(enclosingTypeSeparator); >- String simpleName = this.name.length() == 0 ? Integer.toString(this.occurrenceCount) : this.name; >+ String simpleName = this.name.length() == 0 ? getOccurrenceCountSignature() : this.name; > buffer.append(simpleName); > if (showParameters) { > appendTypeParameters(buffer); > } > return buffer.toString(); > } >- >+ /* >+ * Returns the String representation of the occurrence count for this element. >+ * The occurrence count is a unique number representation to identify the particular element. >+ * >+ * @return the occurrence count for this element in the form of String >+ */ >+ protected String getOccurrenceCountSignature() { >+ return Integer.toString(this.occurrenceCount); >+ } > protected ITypeParameter[] getTypeParameters() throws JavaModelException { > return null; > } >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java >index 9fb59c6..817fc9b 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -154,11 +154,15 @@ > return computeChildren(info, underlyingResource); > } > >-SourceMapper createSourceMapper(IPath sourcePath, IPath rootPath) { >+SourceMapper createSourceMapper(IPath sourcePath, IPath rootPath) throws JavaModelException { >+ IClasspathEntry entry = ((JavaProject) getParent()).getClasspathEntryFor(getPath()); >+ String encoding = (entry== null) ? null : ((ClasspathEntry) entry).getSourceAttachmentEncoding(); > SourceMapper mapper = new SourceMapper( > sourcePath, > rootPath == null ? null : rootPath.toOSString(), >- getJavaProject().getOptions(true)); // cannot use workspace options if external jar is 1.5 jar and workspace options are 1.4 options >+ getJavaProject().getOptions(true),// cannot use workspace options if external jar is 1.5 jar and workspace options are 1.4 options >+ encoding); >+ > return mapper; > } > /* >@@ -707,6 +711,14 @@ > return resource().hashCode(); > } > >+public boolean ignoreOptionalProblems() { >+ try { >+ return ((PackageFragmentRootInfo) getElementInfo()).ignoreOptionalProblems(this); >+ } catch (JavaModelException e) { >+ return false; >+ } >+} >+ > /** > * @see IPackageFragmentRoot > */ >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRootInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRootInfo.java >index 22333a8..431b9c7 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRootInfo.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRootInfo.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2008 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -41,11 +41,15 @@ > * A array with all the non-java resources contained by this PackageFragment > */ > protected Object[] nonJavaResources; >+ >+ private boolean ignoreOptionalProblems; >+ private boolean initialized; > /** > * Create and initialize a new instance of the receiver > */ > public PackageFragmentRootInfo() { > this.nonJavaResources = null; >+ this.initialized = false; > } > /** > * Starting at this folder, create non-java resources for this package fragment root >@@ -155,6 +159,13 @@ > protected SourceMapper getSourceMapper() { > return this.sourceMapper; > } >+boolean ignoreOptionalProblems(PackageFragmentRoot packageFragmentRoot) throws JavaModelException { >+ if (this.initialized == false) { >+ this.ignoreOptionalProblems = ((ClasspathEntry) packageFragmentRoot.getRawClasspathEntry()).ignoreOptionalProblems(); >+ this.initialized = true; >+ } >+ return this.ignoreOptionalProblems; >+} > private static boolean isClasspathEntry(IPath path, IClasspathEntry[] resolvedClasspath) { > for (int i = 0, length = resolvedClasspath.length; i < length; i++) { > IClasspathEntry entry = resolvedClasspath[i]; >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceType.java >index 19aa916..4a02dd4 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceType.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceType.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2004, 2008 IBM Corporation and others. >+ * Copyright (c) 2004, 2012 IBM Corporation 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 >@@ -59,8 +59,9 @@ > } > > public JavaElement unresolved() { >- SourceRefElement handle = new SourceType(this.parent, this.name); >+ SourceType handle = new SourceType(this.parent, this.name); > handle.occurrenceCount = this.occurrenceCount; >+ handle.localOccurrenceCount = this.localOccurrenceCount; > return handle; > } > } >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SelectionRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SelectionRequestor.java >index 4ccb14f..7accbff 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SelectionRequestor.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SelectionRequestor.java >@@ -341,7 +341,7 @@ > } > } > public void acceptLocalMethod(MethodBinding methodBinding) { >- IJavaElement res = findLocalElement(methodBinding.sourceStart()); >+ IJavaElement res = findLocalElement(methodBinding.original().sourceStart()); > if(res != null) { > if(res.getElementType() == IJavaElement.METHOD) { > IMethod method = (IMethod) res; >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SetClasspathOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SetClasspathOperation.java >index 9623813..ec0ccf2 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SetClasspathOperation.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SetClasspathOperation.java >@@ -114,6 +114,7 @@ > IJavaModelStatus status = super.verify(); > if (!status.isOK()) > return status; >+ this.project.flushClasspathProblemMarkers(false, false, true); > return ClasspathEntry.validateClasspath( this.project, this.newRawClasspath, this.newOutputLocation); > } > >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java >index b2302d6..8c14620 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java >@@ -246,10 +246,11 @@ > int anonymousCounter; > int anonymousClassName; > >+ String encoding; >+ String defaultEncoding; > /** > *Options to be used > */ >- String encoding; > Map options; > > /** >@@ -261,15 +262,19 @@ > this.areRootPathsComputed = false; > } > >+ public SourceMapper(IPath sourcePath, String rootPath, Map options) { >+ this(sourcePath, rootPath, options, null); >+ } > /** > * Creates a <code>SourceMapper</code> that locates source in the zip file > * at the given location in the specified package fragment root. > */ >- public SourceMapper(IPath sourcePath, String rootPath, Map options) { >+ public SourceMapper(IPath sourcePath, String rootPath, Map options, String encoding) { > this.areRootPathsComputed = false; > this.options = options; >+ this.encoding = encoding; > try { >- this.encoding = ResourcesPlugin.getWorkspace().getRoot().getDefaultCharset(); >+ this.defaultEncoding = ResourcesPlugin.getWorkspace().getRoot().getDefaultCharset(); > } catch (CoreException e) { > // use no encoding > } >@@ -1020,9 +1025,17 @@ > IResource res = ((IContainer)target).findMember(fullName); > if (res instanceof IFile) { > try { >- source = org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray((IFile)res); >+ // Order of preference: charSet supplied, this.encoding or this.defaultEncoding in that order >+ try { >+ // Use the implicit encoding only when the source attachment's encoding hasn't been explicitly set. >+ charSet = ((IFile) res).getCharset(this.encoding == null); >+ } catch (CoreException e) { >+ // Ignore >+ } >+ source = org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray((IFile) res, >+ charSet == null ? (this.encoding == null ? this.defaultEncoding : this.encoding) : charSet); > } catch (JavaModelException e) { >- // ignore >+ // Ignore > } > } > } else { >@@ -1030,7 +1043,7 @@ > // https://bugs.eclipse.org/bugs/show_bug.cgi?id=303511 > // For a resource inside the workspace, use the encoding set on the resource > if (target instanceof IFile) >- charSet = ((IFile)target).getCharset(); >+ charSet = ((IFile)target).getCharset(this.encoding == null); > } catch (CoreException e) { > // Ignore > } >@@ -1414,7 +1427,8 @@ > try { > byte[] bytes = Util.getZipEntryByteContent(entry, zip); > if (bytes != null) { >- return Util.bytesToChar(bytes, charSet == null ? this.encoding : charSet); >+ // Order of preference: charSet supplied, this.encoding or this.defaultEncoding in that order >+ return Util.bytesToChar(bytes, charSet == null ? (this.encoding == null ? this.defaultEncoding : this.encoding) : charSet); > } > } catch (IOException e) { > // ignore >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceType.java >index 2ce790d..98263ec 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceType.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceType.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2008 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -35,6 +35,12 @@ > */ > > public class SourceType extends NamedMember implements IType { >+ >+/* >+ * A count to uniquely identify this element within the context of the enclosing type. >+ * Currently this is computed and used only for anonymous types. >+ */ >+public int localOccurrenceCount = 1; > > protected SourceType(JavaElement parent, String name) { > super(parent, name); >@@ -274,6 +280,13 @@ > */ > public String getFullyQualifiedParameterizedName() throws JavaModelException { > return getFullyQualifiedName('.', true/*show parameters*/); >+} >+/* >+ * For source types, the occurrence count is the one computed in the context of the immediately enclosing type. >+ * >+ */ >+protected String getOccurrenceCountSignature() { >+ return Integer.toString(this.localOccurrenceCount); > } > /* > * @see JavaElement >@@ -815,8 +828,9 @@ > return op.getResult(); > } > public JavaElement resolved(Binding binding) { >- SourceRefElement resolvedHandle = new ResolvedSourceType(this.parent, this.name, new String(binding.computeUniqueKey())); >+ ResolvedSourceType resolvedHandle = new ResolvedSourceType(this.parent, this.name, new String(binding.computeUniqueKey())); > resolvedHandle.occurrenceCount = this.occurrenceCount; >+ resolvedHandle.localOccurrenceCount = this.localOccurrenceCount; > return resolvedHandle; > } > /** >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathLocation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathLocation.java >index 89d1d67..aef33e1 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathLocation.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathLocation.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2006 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -18,8 +18,8 @@ > > public abstract class ClasspathLocation { > >-static ClasspathLocation forSourceFolder(IContainer sourceFolder, IContainer outputFolder, char[][] inclusionPatterns, char[][] exclusionPatterns) { >- return new ClasspathMultiDirectory(sourceFolder, outputFolder, inclusionPatterns, exclusionPatterns); >+static ClasspathLocation forSourceFolder(IContainer sourceFolder, IContainer outputFolder, char[][] inclusionPatterns, char[][] exclusionPatterns, boolean ignoreOptionalProblems) { >+ return new ClasspathMultiDirectory(sourceFolder, outputFolder, inclusionPatterns, exclusionPatterns, ignoreOptionalProblems); > } > > public static ClasspathLocation forBinaryFolder(IContainer binaryFolder, boolean isOutputFolder, AccessRuleSet accessRuleSet) { >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathMultiDirectory.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathMultiDirectory.java >index 1273281..3d41e08 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathMultiDirectory.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathMultiDirectory.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -15,20 +15,22 @@ > import org.eclipse.jdt.core.compiler.CharOperation; > import org.eclipse.jdt.internal.core.util.Util; > >-class ClasspathMultiDirectory extends ClasspathDirectory { >+public class ClasspathMultiDirectory extends ClasspathDirectory { > > IContainer sourceFolder; > char[][] inclusionPatterns; // used by builders when walking source folders > char[][] exclusionPatterns; // used by builders when walking source folders > boolean hasIndependentOutputFolder; // if output folder is not equal to any of the source folders >+public boolean ignoreOptionalProblems; > >-ClasspathMultiDirectory(IContainer sourceFolder, IContainer binaryFolder, char[][] inclusionPatterns, char[][] exclusionPatterns) { >+ClasspathMultiDirectory(IContainer sourceFolder, IContainer binaryFolder, char[][] inclusionPatterns, char[][] exclusionPatterns, boolean ignoreOptionalProblems) { > super(binaryFolder, true, null); > > this.sourceFolder = sourceFolder; > this.inclusionPatterns = inclusionPatterns; > this.exclusionPatterns = exclusionPatterns; > this.hasIndependentOutputFolder = false; >+ this.ignoreOptionalProblems = ignoreOptionalProblems; > > // handle the case when a state rebuilds a source folder > if (this.inclusionPatterns != null && this.inclusionPatterns.length == 0) >@@ -42,7 +44,8 @@ > if (!(o instanceof ClasspathMultiDirectory)) return false; > > ClasspathMultiDirectory md = (ClasspathMultiDirectory) o; >- return this.sourceFolder.equals(md.sourceFolder) && this.binaryFolder.equals(md.binaryFolder) >+ return this.ignoreOptionalProblems == md.ignoreOptionalProblems >+ && this.sourceFolder.equals(md.sourceFolder) && this.binaryFolder.equals(md.binaryFolder) > && CharOperation.equals(this.inclusionPatterns, md.inclusionPatterns) > && CharOperation.equals(this.exclusionPatterns, md.exclusionPatterns); > } >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameEnvironment.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameEnvironment.java >index 66fde98..65c3c79 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameEnvironment.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameEnvironment.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2008 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -114,7 +114,7 @@ > createOutputFolder(outputFolder); > } > sLocations.add( >- ClasspathLocation.forSourceFolder((IContainer) target, outputFolder, entry.fullInclusionPatternChars(), entry.fullExclusionPatternChars())); >+ ClasspathLocation.forSourceFolder((IContainer) target, outputFolder, entry.fullInclusionPatternChars(), entry.fullExclusionPatternChars(), entry.ignoreOptionalProblems())); > continue nextEntry; > > case IClasspathEntry.CPE_PROJECT : >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/SourceFile.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/SourceFile.java >index 4955f5d..4a5b04d 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/SourceFile.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/SourceFile.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -103,6 +103,9 @@ > public int hashCode() { > return this.initialTypeName.hashCode(); > } >+public boolean ignoreOptionalProblems() { >+ return this.sourceLocation.ignoreOptionalProblems; >+} > String typeLocator() { > return this.resource.getProjectRelativePath().toString(); > } >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java >index 682073d..6dfb1ec 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -27,7 +27,7 @@ > // NOTE: this state cannot contain types that are not defined in this project > > String javaProjectName; >-ClasspathMultiDirectory[] sourceLocations; >+public ClasspathMultiDirectory[] sourceLocations; > ClasspathLocation[] binaryLocations; > // keyed by the project relative path of the type (i.e. "src1/p1/p2/A.java"), value is a ReferenceCollection or an AdditionalTypeCollection > SimpleLookupTable references; >@@ -44,7 +44,7 @@ > private StringSet structurallyChangedTypes; > public static int MaxStructurallyChangedTypes = 100; // keep track of ? structurally changed types, otherwise consider all to be changed > >-public static final byte VERSION = 0x0019; // fix for 325755 >+public static final byte VERSION = 0x001B; > > static final byte SOURCE_FOLDER = 1; > static final byte BINARY_FOLDER = 2; >@@ -246,7 +246,7 @@ > if ((folderName = in.readUTF()).length() > 0) sourceFolder = project.getFolder(folderName); > if ((folderName = in.readUTF()).length() > 0) outputFolder = project.getFolder(folderName); > ClasspathMultiDirectory md = >- (ClasspathMultiDirectory) ClasspathLocation.forSourceFolder(sourceFolder, outputFolder, readNames(in), readNames(in)); >+ (ClasspathMultiDirectory) ClasspathLocation.forSourceFolder(sourceFolder, outputFolder, readNames(in), readNames(in), in.readBoolean()); > if (in.readBoolean()) > md.hasIndependentOutputFolder = true; > newState.sourceLocations[i] = md; >@@ -425,6 +425,7 @@ > out.writeUTF(md.binaryFolder.getProjectRelativePath().toString()); > writeNames(md.inclusionPatterns, out); > writeNames(md.exclusionPatterns, out); >+ out.writeBoolean(md.ignoreOptionalProblems); > out.writeBoolean(md.hasIndependentOutputFolder); > } > >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java >index 0513604..4cc7768 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java >@@ -846,6 +846,8 @@ > char[][] memberTypeNames = CharOperation.splitOn('$', typeName, firstDollar+1, typeName.length); > for (int i = 0; i < memberTypeNames.length; i++) { > this.focusType = this.focusType.getMemberType(memberTypeNames[i]); >+ if (this.focusType == null) >+ return null; > } > } > } >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/CompilationUnit.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/CompilationUnit.java >index fc64497..c00aa48 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/CompilationUnit.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/CompilationUnit.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -51,6 +51,9 @@ > public char[][] getPackageName() { > return null; > } >+public boolean ignoreOptionalProblems() { >+ return false; >+} > public String toString() { > return "CompilationUnit[" + new String(this.fFileName) + "]"; //$NON-NLS-2$ //$NON-NLS-1$ > } >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BootstrapMethodsAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BootstrapMethodsAttribute.java >new file mode 100644 >index 0000000..b196927 >--- /dev/null >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BootstrapMethodsAttribute.java >@@ -0,0 +1,63 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 IBM Corporation 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.internal.core.util; >+ >+import org.eclipse.jdt.core.util.ClassFormatException; >+import org.eclipse.jdt.core.util.IBootstrapMethodsAttribute; >+import org.eclipse.jdt.core.util.IBootstrapMethodsEntry; >+import org.eclipse.jdt.core.util.IConstantPool; >+ >+/** >+ * Default implementation of IBootstrapMethodsAttribute. >+ */ >+public class BootstrapMethodsAttribute extends ClassFileAttribute implements IBootstrapMethodsAttribute { >+ private static final IBootstrapMethodsEntry[] NO_ENTRIES = new IBootstrapMethodsEntry[0]; >+ >+ private IBootstrapMethodsEntry[] entries; >+ private int numberOfBootstrapMethods; >+ >+ /** >+ * Constructor for BootstrapMethodsAttribute. >+ * @param classFileBytes >+ * @param constantPool >+ * @param offset >+ * @throws ClassFormatException >+ */ >+ public BootstrapMethodsAttribute( >+ byte[] classFileBytes, >+ IConstantPool constantPool, >+ int offset) throws ClassFormatException { >+ super(classFileBytes, constantPool, offset); >+ this.numberOfBootstrapMethods = u2At(classFileBytes, 6, offset); >+ final int length = this.numberOfBootstrapMethods; >+ if (length != 0) { >+ int readOffset = 8; >+ this.entries = new IBootstrapMethodsEntry[length]; >+ for (int i = 0; i < length; i++) { >+ this.entries[i] = new BootstrapMethodsEntry(classFileBytes, constantPool, offset + readOffset); >+ readOffset += 8; >+ } >+ } else { >+ this.entries = NO_ENTRIES; >+ } >+ } >+ >+ /** >+ * @see IBootstrapMethodsAttribute#getBootstrapMethods() >+ */ >+ public IBootstrapMethodsEntry[] getBootstrapMethods() { >+ return this.entries; >+ } >+ >+ public int getBootstrapMethodsLength() { >+ return this.numberOfBootstrapMethods; >+ } >+} >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BootstrapMethodsEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BootstrapMethodsEntry.java >new file mode 100644 >index 0000000..e444dbd >--- /dev/null >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BootstrapMethodsEntry.java >@@ -0,0 +1,52 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 IBM Corporation 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.internal.core.util; >+ >+import org.eclipse.jdt.core.util.ClassFormatException; >+import org.eclipse.jdt.core.util.IBootstrapMethodsEntry; >+import org.eclipse.jdt.core.util.IConstantPool; >+ >+/** >+ * Default implementation of {@link IBootstrapMethodsEntry} >+ */ >+public class BootstrapMethodsEntry >+ extends ClassFileStruct >+ implements IBootstrapMethodsEntry { >+ >+ private int bootstrapMethodReference; >+ private int[] bootstrapArguments; >+ >+ public BootstrapMethodsEntry(byte classFileBytes[], IConstantPool constantPool, int offset) throws ClassFormatException { >+ this.bootstrapMethodReference = u2At(classFileBytes, 0, offset); >+ int length = u2At(classFileBytes, 2, offset); >+ int[] arguments = new int[length]; >+ int position = 4; >+ for (int i = 0; i < length; i++) { >+ arguments[i] = u2At(classFileBytes, position, offset); >+ position += 2; >+ } >+ this.bootstrapArguments = arguments; >+ } >+ >+ /** >+ * @see IBootstrapMethodsEntry#getBootstrapArguments() >+ */ >+ public int[] getBootstrapArguments() { >+ return this.bootstrapArguments; >+ } >+ >+ /** >+ * @see IBootstrapMethodsEntry#getBootstrapMethodReference() >+ */ >+ public int getBootstrapMethodReference() { >+ return this.bootstrapMethodReference; >+ } >+} >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileReader.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileReader.java >index 19b80dc..0426dc4 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileReader.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileReader.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2008 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -140,6 +140,18 @@ > constantPoolOffsets[i] = readOffset; > readOffset += IConstantPoolConstant.CONSTANT_NameAndType_SIZE; > break; >+ case IConstantPoolConstant.CONSTANT_MethodHandle : >+ constantPoolOffsets[i] = readOffset; >+ readOffset += IConstantPoolConstant.CONSTANT_MethodHandle_SIZE; >+ break; >+ case IConstantPoolConstant.CONSTANT_MethodType : >+ constantPoolOffsets[i] = readOffset; >+ readOffset += IConstantPoolConstant.CONSTANT_MethodType_SIZE; >+ break; >+ case IConstantPoolConstant.CONSTANT_InvokeDynamic : >+ constantPoolOffsets[i] = readOffset; >+ readOffset += IConstantPoolConstant.CONSTANT_InvokeDynamic_SIZE; >+ break; > default: > throw new ClassFormatException(ClassFormatException.INVALID_TAG_CONSTANT); > } >@@ -261,6 +273,8 @@ > this.attributes[attributesIndex++] = new RuntimeVisibleAnnotationsAttribute(classFileBytes, this.constantPool, readOffset); > } else if (equals(attributeName, IAttributeNamesConstants.RUNTIME_INVISIBLE_ANNOTATIONS)) { > this.attributes[attributesIndex++] = new RuntimeInvisibleAnnotationsAttribute(classFileBytes, this.constantPool, readOffset); >+ } else if (equals(attributeName, IAttributeNamesConstants.BOOTSTRAP_METHODS)) { >+ this.attributes[attributesIndex++] = new BootstrapMethodsAttribute(classFileBytes, this.constantPool, readOffset); > } else { > this.attributes[attributesIndex++] = new ClassFileAttribute(classFileBytes, this.constantPool, readOffset); > } >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CodeAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CodeAttribute.java >index 82ba955..a281ab0 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CodeAttribute.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CodeAttribute.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -1049,14 +1049,13 @@ > case IOpcodeMnemonics.INVOKEDYNAMIC : > index = u2At(this.classFileBytes, 1, pc); > constantPoolEntry = this.constantPool.decodeEntry(index); >- if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_NameAndType) { >+ if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_InvokeDynamic) { > throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY); > } > visitor._invokedynamic( > pc - this.codeOffset, > index, >- this.constantPool.decodeEntry(constantPoolEntry.getNameAndTypeInfoNameIndex()), >- this.constantPool.decodeEntry(constantPoolEntry.getNameAndTypeInfoDescriptorIndex())); >+ constantPoolEntry); > pc += 5; > break; > case IOpcodeMnemonics.NEW : >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPool.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPool.java >index aeeee24..a9c4699 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPool.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPool.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -33,19 +33,28 @@ > * @see IConstantPool#decodeEntry(int) > */ > public IConstantPoolEntry decodeEntry(int index) { >- ConstantPoolEntry constantPoolEntry = new ConstantPoolEntry(); >- constantPoolEntry.reset(); >+ ConstantPoolEntry constantPoolEntry = null; > int kind = getEntryKind(index); >- constantPoolEntry.setKind(kind); > switch(kind) { > case IConstantPoolConstant.CONSTANT_Class : >+ constantPoolEntry = new ConstantPoolEntry(); >+ constantPoolEntry.reset(); >+ constantPoolEntry.setKind(kind); > constantPoolEntry.setClassInfoNameIndex(u2At(this.classFileBytes, 1, this.constantPoolOffset[index])); > constantPoolEntry.setClassInfoName(getUtf8ValueAt(constantPoolEntry.getClassInfoNameIndex())); > break; > case IConstantPoolConstant.CONSTANT_Double : >+ constantPoolEntry = new ConstantPoolEntry(); >+ constantPoolEntry.reset(); >+ constantPoolEntry.setKind(kind); > constantPoolEntry.setDoubleValue(doubleAt(this.classFileBytes, 1, this.constantPoolOffset[index])); > break; > case IConstantPoolConstant.CONSTANT_Fieldref : >+ constantPoolEntry = new ConstantPoolEntry(); >+ constantPoolEntry.reset(); >+ constantPoolEntry.setKind(kind); >+ constantPoolEntry.reset(); >+ constantPoolEntry.setKind(kind); > constantPoolEntry.setClassIndex(u2At(this.classFileBytes, 1, this.constantPoolOffset[index])); > int declaringClassIndex = u2At(this.classFileBytes, 1, this.constantPoolOffset[constantPoolEntry.getClassIndex()]); > constantPoolEntry.setClassName(getUtf8ValueAt(declaringClassIndex)); >@@ -57,6 +66,11 @@ > break; > case IConstantPoolConstant.CONSTANT_Methodref : > case IConstantPoolConstant.CONSTANT_InterfaceMethodref : >+ constantPoolEntry = new ConstantPoolEntry(); >+ constantPoolEntry.reset(); >+ constantPoolEntry.setKind(kind); >+ constantPoolEntry.reset(); >+ constantPoolEntry.setKind(kind); > constantPoolEntry.setClassIndex(u2At(this.classFileBytes, 1, this.constantPoolOffset[index])); > declaringClassIndex = u2At(this.classFileBytes, 1, this.constantPoolOffset[constantPoolEntry.getClassIndex()]); > constantPoolEntry.setClassName(getUtf8ValueAt(declaringClassIndex)); >@@ -67,25 +81,76 @@ > constantPoolEntry.setMethodDescriptor(getUtf8ValueAt(methodDescriptorIndex)); > break; > case IConstantPoolConstant.CONSTANT_Float : >+ constantPoolEntry = new ConstantPoolEntry(); >+ constantPoolEntry.reset(); >+ constantPoolEntry.setKind(kind); >+ constantPoolEntry.reset(); >+ constantPoolEntry.setKind(kind); > constantPoolEntry.setFloatValue(floatAt(this.classFileBytes, 1, this.constantPoolOffset[index])); > break; > case IConstantPoolConstant.CONSTANT_Integer : >+ constantPoolEntry = new ConstantPoolEntry(); >+ constantPoolEntry.reset(); >+ constantPoolEntry.setKind(kind); > constantPoolEntry.setIntegerValue(i4At(this.classFileBytes, 1, this.constantPoolOffset[index])); > break; > case IConstantPoolConstant.CONSTANT_Long : >+ constantPoolEntry = new ConstantPoolEntry(); >+ constantPoolEntry.reset(); >+ constantPoolEntry.setKind(kind); > constantPoolEntry.setLongValue(i8At(this.classFileBytes, 1, this.constantPoolOffset[index])); > break; > case IConstantPoolConstant.CONSTANT_NameAndType : >+ constantPoolEntry = new ConstantPoolEntry(); >+ constantPoolEntry.reset(); >+ constantPoolEntry.setKind(kind); > constantPoolEntry.setNameAndTypeNameIndex(u2At(this.classFileBytes, 1, this.constantPoolOffset[index])); > constantPoolEntry.setNameAndTypeDescriptorIndex(u2At(this.classFileBytes, 3, this.constantPoolOffset[index])); > break; > case IConstantPoolConstant.CONSTANT_String : >+ constantPoolEntry = new ConstantPoolEntry(); >+ constantPoolEntry.reset(); >+ constantPoolEntry.setKind(kind); > constantPoolEntry.setStringIndex(u2At(this.classFileBytes, 1, this.constantPoolOffset[index])); > constantPoolEntry.setStringValue(getUtf8ValueAt(constantPoolEntry.getStringIndex())); > break; > case IConstantPoolConstant.CONSTANT_Utf8 : >+ constantPoolEntry = new ConstantPoolEntry(); >+ constantPoolEntry.reset(); >+ constantPoolEntry.setKind(kind); > constantPoolEntry.setUtf8Length(u2At(this.classFileBytes, 1, this.constantPoolOffset[index])); > constantPoolEntry.setUtf8Value(getUtf8ValueAt(index)); >+ break; >+ case IConstantPoolConstant.CONSTANT_MethodHandle : >+ ConstantPoolEntry2 constantPoolEntry2 = new ConstantPoolEntry2(); >+ constantPoolEntry2.reset(); >+ constantPoolEntry2.setKind(kind); >+ constantPoolEntry2.setReferenceKind(u1At(this.classFileBytes, 1, this.constantPoolOffset[index])); >+ constantPoolEntry2.setReferenceIndex(u2At(this.classFileBytes, 2, this.constantPoolOffset[index])); >+ constantPoolEntry = constantPoolEntry2; >+ break; >+ case IConstantPoolConstant.CONSTANT_MethodType : >+ constantPoolEntry2 = new ConstantPoolEntry2(); >+ constantPoolEntry2.reset(); >+ constantPoolEntry2.setKind(kind); >+ methodDescriptorIndex = u2At(this.classFileBytes, 1, this.constantPoolOffset[index]); >+ constantPoolEntry2.setDescriptorIndex(methodDescriptorIndex); >+ constantPoolEntry2.setMethodDescriptor(getUtf8ValueAt(methodDescriptorIndex)); >+ constantPoolEntry = constantPoolEntry2; >+ break; >+ case IConstantPoolConstant.CONSTANT_InvokeDynamic : >+ constantPoolEntry2 = new ConstantPoolEntry2(); >+ constantPoolEntry2.reset(); >+ constantPoolEntry2.setKind(kind); >+ constantPoolEntry2.setBootstrapMethodAttributeIndex(u2At(this.classFileBytes, 1, this.constantPoolOffset[index])); >+ int nameAndTypeIndex = u2At(this.classFileBytes, 3, this.constantPoolOffset[index]); >+ constantPoolEntry2.setNameAndTypeIndex(nameAndTypeIndex); >+ methodNameIndex = u2At(this.classFileBytes, 1, this.constantPoolOffset[nameAndTypeIndex]); >+ methodDescriptorIndex = u2At(this.classFileBytes, 3, this.constantPoolOffset[nameAndTypeIndex]); >+ constantPoolEntry2.setMethodName(getUtf8ValueAt(methodNameIndex)); >+ constantPoolEntry2.setMethodDescriptor(getUtf8ValueAt(methodDescriptorIndex)); >+ constantPoolEntry = constantPoolEntry2; >+ break; > } > return constantPoolEntry; > } >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPoolEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPoolEntry.java >index 55cc170..9f9cae6 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPoolEntry.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPoolEntry.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2008 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -341,6 +341,7 @@ > > /** > * Sets the methodDescriptor. >+ * > * @param methodDescriptor The methodDescriptor to set > */ > public void setMethodDescriptor(char[] methodDescriptor) { >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPoolEntry2.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPoolEntry2.java >new file mode 100644 >index 0000000..c6c9686 >--- /dev/null >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPoolEntry2.java >@@ -0,0 +1,66 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2011 IBM Corporation 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.internal.core.util; >+ >+import org.eclipse.jdt.core.util.IConstantPoolEntry2; >+ >+/** >+ * Default implementation of IConstantPoolEntry >+ * >+ * @since 2.0 >+ */ >+public class ConstantPoolEntry2 extends ConstantPoolEntry implements IConstantPoolEntry2 { >+ >+ private int descriptorIndex; >+ private int referenceKind; >+ private int referenceIndex; >+ private int bootstrapMethodAttributeIndex; >+ >+ public int getDescriptorIndex() { >+ return this.descriptorIndex; >+ } >+ >+ public int getReferenceKind() { >+ return this.referenceKind; >+ } >+ >+ public int getReferenceIndex() { >+ return this.referenceIndex; >+ } >+ >+ public int getBootstrapMethodAttributeIndex() { >+ return this.bootstrapMethodAttributeIndex; >+ } >+ >+ public void setDescriptorIndex(int descriptorIndex) { >+ this.descriptorIndex = descriptorIndex; >+ } >+ >+ public void setReferenceKind(int referenceKind) { >+ this.referenceKind = referenceKind; >+ } >+ >+ public void setReferenceIndex(int referenceIndex) { >+ this.referenceIndex = referenceIndex; >+ } >+ >+ public void setBootstrapMethodAttributeIndex(int bootstrapMethodAttributeIndex) { >+ this.bootstrapMethodAttributeIndex = bootstrapMethodAttributeIndex; >+ } >+ >+ public void reset() { >+ super.reset(); >+ this.descriptorIndex = 0; >+ this.referenceKind = 0; >+ this.referenceIndex = 0; >+ this.bootstrapMethodAttributeIndex = 0; >+ } >+} >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DefaultBytecodeVisitor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DefaultBytecodeVisitor.java >index d94dd4e..b5fe2ab 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DefaultBytecodeVisitor.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DefaultBytecodeVisitor.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -17,6 +17,7 @@ > import org.eclipse.jdt.core.util.ICodeAttribute; > import org.eclipse.jdt.core.util.IConstantPoolConstant; > import org.eclipse.jdt.core.util.IConstantPoolEntry; >+import org.eclipse.jdt.core.util.IConstantPoolEntry2; > import org.eclipse.jdt.core.util.ILocalVariableAttribute; > import org.eclipse.jdt.core.util.ILocalVariableTableEntry; > import org.eclipse.jdt.core.util.OpcodeStringValues; >@@ -1491,7 +1492,7 @@ > writeNewLine(); > } > /** >- * @see IBytecodeVisitor#_invokedynamic(int, int, IConstantPoolEntry, IConstantPoolEntry) >+ * @see IBytecodeVisitor#_invokedynamic(int, int, IConstantPoolEntry) > */ > public void _invokedynamic( > int pc, >@@ -1513,6 +1514,30 @@ > writeNewLine(); > } > /** >+ * @see IBytecodeVisitor#_invokedynamic(int, int, IConstantPoolEntry) >+ */ >+ public void _invokedynamic( >+ int pc, >+ int index, >+ IConstantPoolEntry invokeDynamicEntry) { >+ >+ dumpPcNumber(pc); >+ IConstantPoolEntry2 entry = (IConstantPoolEntry2) invokeDynamicEntry; >+ this.buffer.append(Messages.bind(Messages.classformat_invokedynamic, >+ new String[] { >+ OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INVOKEDYNAMIC], >+ Integer.toString(index), >+ Integer.toString(entry.getBootstrapMethodAttributeIndex()), >+ Util.toString( >+ null, >+ entry.getMethodName(), >+ entry.getMethodDescriptor(), >+ true, >+ isCompact()) >+ })); >+ writeNewLine(); >+ } >+ /** > * @see IBytecodeVisitor#_invokeinterface(int, int, byte, IConstantPoolEntry) > */ > public void _invokeinterface( >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java >index c54fd73..067a219 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java >@@ -741,7 +741,7 @@ > final int classNameLength = className.length; > final int accessFlags = classFileReader.getAccessFlags(); > final boolean isEnum = (accessFlags & IModifierConstants.ACC_ENUM) != 0; >- >+ > StringBuffer buffer = new StringBuffer(); > ISourceAttribute sourceAttribute = classFileReader.getSourceFileAttribute(); > IClassFileAttribute classFileAttribute = Util.getAttribute(classFileReader, IAttributeNamesConstants.SIGNATURE); >@@ -788,7 +788,7 @@ > } > } > final int lastDotIndexInClassName = CharOperation.lastIndexOf('.', className); >- >+ > if (checkMode(mode, WORKING_COPY) && lastDotIndexInClassName != -1) { > // we print a package declaration > buffer.append("package ");//$NON-NLS-1$ >@@ -796,11 +796,13 @@ > buffer.append(';'); > writeNewLine(buffer, lineSeparator, 0); > } >- >+ > IInnerClassesAttribute innerClassesAttribute = classFileReader.getInnerClassesAttribute(); > IClassFileAttribute runtimeVisibleAnnotationsAttribute = Util.getAttribute(classFileReader, IAttributeNamesConstants.RUNTIME_VISIBLE_ANNOTATIONS); > IClassFileAttribute runtimeInvisibleAnnotationsAttribute = Util.getAttribute(classFileReader, IAttributeNamesConstants.RUNTIME_INVISIBLE_ANNOTATIONS); >- >+ >+ IClassFileAttribute bootstrapMethods = Util.getAttribute(classFileReader, IAttributeNamesConstants.BOOTSTRAP_METHODS); >+ > if (checkMode(mode, DETAILED)) { > // disassemble compact version of annotations > if (runtimeInvisibleAnnotationsAttribute != null) { >@@ -838,7 +840,7 @@ > } > } > } >- >+ > final boolean isAnnotation = (accessFlags & IModifierConstants.ACC_ANNOTATION) != 0; > boolean isInterface = false; > if (isEnum) { >@@ -852,7 +854,7 @@ > buffer.append("interface "); //$NON-NLS-1$ > isInterface = true; > } >- >+ > if (checkMode(mode, WORKING_COPY)) { > // we print the simple class name > final int start = lastDotIndexInClassName + 1; >@@ -864,7 +866,7 @@ > } else { > buffer.append(className); > } >- >+ > char[] superclassName = classFileReader.getSuperclassName(); > if (superclassName != null) { > CharOperation.replace(superclassName, '/', '.'); >@@ -917,14 +919,26 @@ > if (signatureAttribute != null) { > remainingAttributesLength--; > } >- if (innerClassesAttribute != null || enclosingMethodAttribute != null || remainingAttributesLength != 0) { >- writeNewLine(buffer, lineSeparator, 0); >+ if (bootstrapMethods != null) { >+ remainingAttributesLength--; >+ } >+ if (innerClassesAttribute != null >+ || enclosingMethodAttribute != null >+ || bootstrapMethods != null >+ || remainingAttributesLength != 0) { >+ // this test is to ensure we don't insert more than one line separator >+ if (buffer.lastIndexOf(lineSeparator) != buffer.length() - lineSeparator.length()) { >+ writeNewLine(buffer, lineSeparator, 0); >+ } > } > if (innerClassesAttribute != null) { > disassemble(innerClassesAttribute, buffer, lineSeparator, 1); > } > if (enclosingMethodAttribute != null) { > disassemble(enclosingMethodAttribute, buffer, lineSeparator, 0); >+ } >+ if (bootstrapMethods != null) { >+ disassemble((IBootstrapMethodsAttribute) bootstrapMethods, buffer, lineSeparator, 0); > } > if (checkMode(mode, SYSTEM)) { > if (runtimeVisibleAnnotationsAttribute != null) { >@@ -937,13 +951,14 @@ > for (int i = 0; i < length; i++) { > IClassFileAttribute attribute = attributes[i]; > if (attribute != innerClassesAttribute >- && attribute != sourceAttribute >- && attribute != signatureAttribute >- && attribute != enclosingMethodAttribute >- && attribute != runtimeInvisibleAnnotationsAttribute >- && attribute != runtimeVisibleAnnotationsAttribute >- && !CharOperation.equals(attribute.getAttributeName(), IAttributeNamesConstants.DEPRECATED) >- && !CharOperation.equals(attribute.getAttributeName(), IAttributeNamesConstants.SYNTHETIC)) { >+ && attribute != sourceAttribute >+ && attribute != signatureAttribute >+ && attribute != enclosingMethodAttribute >+ && attribute != runtimeInvisibleAnnotationsAttribute >+ && attribute != runtimeVisibleAnnotationsAttribute >+ && !CharOperation.equals(attribute.getAttributeName(), IAttributeNamesConstants.DEPRECATED) >+ && !CharOperation.equals(attribute.getAttributeName(), IAttributeNamesConstants.SYNTHETIC) >+ && attribute != bootstrapMethods) { > disassemble(attribute, buffer, lineSeparator, 0, mode); > } > } >@@ -1408,8 +1423,72 @@ > Integer.toString(i), > decodeStringValue(new String(constantPoolEntry.getUtf8Value()))})); > break; >+ case IConstantPoolConstant.CONSTANT_MethodHandle : >+ IConstantPoolEntry2 entry2 = (IConstantPoolEntry2) constantPoolEntry; >+ buffer.append( >+ Messages.bind(Messages.disassembler_constantpool_methodhandle, >+ new String[] { >+ Integer.toString(i), >+ getReferenceKind(entry2.getReferenceKind()), >+ Integer.toString(entry2.getReferenceIndex()), >+ })); >+ break; >+ case IConstantPoolConstant.CONSTANT_MethodType : >+ entry2 = (IConstantPoolEntry2) constantPoolEntry; >+ buffer.append( >+ Messages.bind(Messages.disassembler_constantpool_methodtype, >+ new String[] { >+ Integer.toString(i), >+ Integer.toString(entry2.getDescriptorIndex()), >+ String.valueOf(entry2.getMethodDescriptor()), >+ })); >+ break; >+ case IConstantPoolConstant.CONSTANT_InvokeDynamic : >+ entry2 = (IConstantPoolEntry2) constantPoolEntry; >+ buffer.append( >+ Messages.bind(Messages.disassembler_constantpool_invokedynamic, >+ new String[] { >+ Integer.toString(i), >+ Integer.toString(entry2.getBootstrapMethodAttributeIndex()), >+ Integer.toString(entry2.getNameAndTypeIndex()), >+ new String(constantPoolEntry.getMethodName()), >+ new String(constantPoolEntry.getMethodDescriptor()) >+ })); > } > } >+ } >+ >+ private String getReferenceKind(int referenceKind) { >+ String message = null; >+ switch(referenceKind) { >+ case IConstantPoolConstant.METHOD_TYPE_REF_GetField : >+ message = Messages.disassembler_method_type_ref_getfield; >+ break; >+ case IConstantPoolConstant.METHOD_TYPE_REF_GetStatic : >+ message = Messages.disassembler_method_type_ref_getstatic; >+ break; >+ case IConstantPoolConstant.METHOD_TYPE_REF_PutField : >+ message = Messages.disassembler_method_type_ref_putfield; >+ break; >+ case IConstantPoolConstant.METHOD_TYPE_REF_PutStatic : >+ message = Messages.disassembler_method_type_ref_putstatic; >+ break; >+ case IConstantPoolConstant.METHOD_TYPE_REF_InvokeInterface : >+ message = Messages.disassembler_method_type_ref_invokeinterface; >+ break; >+ case IConstantPoolConstant.METHOD_TYPE_REF_InvokeSpecial : >+ message = Messages.disassembler_method_type_ref_invokespecial; >+ break; >+ case IConstantPoolConstant.METHOD_TYPE_REF_InvokeStatic : >+ message = Messages.disassembler_method_type_ref_invokestatic; >+ break; >+ case IConstantPoolConstant.METHOD_TYPE_REF_InvokeVirtual : >+ message = Messages.disassembler_method_type_ref_invokevirtual; >+ break; >+ default : >+ message = Messages.disassembler_method_type_ref_newinvokespecial; >+ } >+ return Messages.bind(message, new String[] { Integer.toString(referenceKind) }); > } > > private void disassemble(IEnclosingMethodAttribute enclosingMethodAttribute, StringBuffer buffer, String lineSeparator, int tabNumber) { >@@ -1669,6 +1748,46 @@ > } > } > >+ private void disassemble(IBootstrapMethodsAttribute bootstrapMethodsAttribute, StringBuffer buffer, String lineSeparator, int tabNumber) { >+ writeNewLine(buffer, lineSeparator, tabNumber); >+ buffer.append(Messages.disassembler_bootstrapmethodattributesheader); >+ writeNewLine(buffer, lineSeparator, tabNumber + 1); >+ IBootstrapMethodsEntry[] entries = bootstrapMethodsAttribute.getBootstrapMethods(); >+ int length = entries.length; >+ for (int i = 0; i < length; i++) { >+ if (i != 0) { >+ buffer.append(Messages.disassembler_comma); >+ writeNewLine(buffer, lineSeparator, tabNumber + 1); >+ } >+ IBootstrapMethodsEntry entry = entries[i]; >+ buffer.append( >+ Messages.bind( >+ Messages.disassembler_bootstrapmethodentry, >+ new String[] { >+ Integer.toString(i), >+ Integer.toString(entry.getBootstrapMethodReference()), >+ getArguments(entry.getBootstrapArguments()) >+ })); >+ } >+ } >+ >+ private String getArguments(int[] arguments) { >+ StringBuffer buffer = new StringBuffer(); >+ buffer.append('{'); >+ for (int i = 0, max = arguments.length; i < max; i++) { >+ if (i != 0) { >+ buffer.append(Messages.disassembler_comma); >+ } >+ buffer.append( >+ Messages.bind( >+ Messages.disassembler_bootstrapmethodentry_argument, >+ new String[] { >+ Integer.toString(arguments[i]), >+ })); >+ } >+ buffer.append('}'); >+ return String.valueOf(buffer); >+ } > private void disassemble(int index, IParameterAnnotation parameterAnnotation, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) { > IAnnotation[] annotations = parameterAnnotation.getAnnotations(); > writeNewLine(buffer, lineSeparator, tabNumber + 1); >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java >index 75ecbab..ff1cf83 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java >@@ -259,6 +259,9 @@ > public static String disassembler_inner_accessflags; > public static String disassembler_genericattributeheader; > public static String disassembler_signatureattributeheader; >+ public static String disassembler_bootstrapmethodattributesheader; >+ public static String disassembler_bootstrapmethodentry; >+ public static String disassembler_bootstrapmethodentry_argument; > public static String disassembler_indentation; > public static String disassembler_constantpoolindex; > public static String disassembler_space; >@@ -278,6 +281,9 @@ > public static String disassembler_constantpool_methodref; > public static String disassembler_constantpool_name_and_type; > public static String disassembler_constantpool_utf8; >+ public static String disassembler_constantpool_methodhandle; >+ public static String disassembler_constantpool_methodtype; >+ public static String disassembler_constantpool_invokedynamic; > public static String disassembler_annotationdefaultheader; > public static String disassembler_annotationdefaultvalue; > public static String disassembler_annotationenumvalue; >@@ -348,6 +354,16 @@ > public static String disassembler_frame_same_frame; > public static String disassembler_frame_same_locals_1_stack_item; > public static String code_assist_internal_error; >+ >+ public static String disassembler_method_type_ref_getfield; >+ public static String disassembler_method_type_ref_putfield; >+ public static String disassembler_method_type_ref_getstatic; >+ public static String disassembler_method_type_ref_putstatic; >+ public static String disassembler_method_type_ref_invokestatic; >+ public static String disassembler_method_type_ref_invokevirtual; >+ public static String disassembler_method_type_ref_invokespecial; >+ public static String disassembler_method_type_ref_invokeinterface; >+ public static String disassembler_method_type_ref_newinvokespecial; > > static { > NLS.initializeMessages(BUNDLE_NAME, Messages.class); >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/PublicScanner.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/PublicScanner.java >index db2eade..92cc37e 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/PublicScanner.java >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/PublicScanner.java >@@ -1817,13 +1817,13 @@ > this.currentPosition += (this.eofPosition - this.currentPosition); > throw new InvalidInputException(INVALID_UNICODE_ESCAPE); > } >- if ((c1 = ScannerHelper.getNumericValue(this.source[this.currentPosition++])) > 15 >+ if ((c1 = ScannerHelper.getHexadecimalValue(this.source[this.currentPosition++])) > 15 > || c1 < 0 >- || (c2 = ScannerHelper.getNumericValue(this.source[this.currentPosition++])) > 15 >+ || (c2 = ScannerHelper.getHexadecimalValue(this.source[this.currentPosition++])) > 15 > || c2 < 0 >- || (c3 = ScannerHelper.getNumericValue(this.source[this.currentPosition++])) > 15 >+ || (c3 = ScannerHelper.getHexadecimalValue(this.source[this.currentPosition++])) > 15 > || c3 < 0 >- || (c4 = ScannerHelper.getNumericValue(this.source[this.currentPosition++])) > 15 >+ || (c4 = ScannerHelper.getHexadecimalValue(this.source[this.currentPosition++])) > 15 > || c4 < 0){ > throw new InvalidInputException(INVALID_UNICODE_ESCAPE); > } >@@ -2723,18 +2723,18 @@ > // OctalDigit OctalDigit > // ZeroToThree OctalDigit OctalDigit > >- int number = ScannerHelper.getNumericValue(this.currentCharacter); >+ int number = ScannerHelper.getHexadecimalValue(this.currentCharacter); > if (number >= 0 && number <= 7) { > boolean zeroToThreeNot = number > 3; > if (ScannerHelper.isDigit(this.currentCharacter = this.source[this.currentPosition++])) { >- int digit = ScannerHelper.getNumericValue(this.currentCharacter); >+ int digit = ScannerHelper.getHexadecimalValue(this.currentCharacter); > if (digit >= 0 && digit <= 7) { > number = (number * 8) + digit; > if (ScannerHelper.isDigit(this.currentCharacter = this.source[this.currentPosition++])) { > if (zeroToThreeNot) {// has read \NotZeroToThree OctalDigit Digit --> ignore last character > this.currentPosition--; > } else { >- digit = ScannerHelper.getNumericValue(this.currentCharacter); >+ digit = ScannerHelper.getHexadecimalValue(this.currentCharacter); > if (digit >= 0 && digit <= 7){ // has read \ZeroToThree OctalDigit OctalDigit > number = (number * 8) + digit; > } else {// has read \ZeroToThree OctalDigit NonOctalDigit --> ignore last character >diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties >index e75e56b..5af88db 100644 >--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties >+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties >@@ -285,6 +285,9 @@ > disassembler_stackmaptableattributeheader = Stack map table: number of frames {0} > disassembler_stackmapattributeheader = Stack map : number of frames {0} > disassembler_signatureattributeheader = // Signature: {0} >+disassembler_bootstrapmethodattributesheader = Bootstrap methods: >+disassembler_bootstrapmethodentry = {0} : # {1} arguments: {2} >+disassembler_bootstrapmethodentry_argument = #{0} > disassembler_indentation = \ > disassembler_constantpoolindex =\ # > disassembler_space = \ >@@ -304,6 +307,9 @@ > disassembler_constantpool_methodref = constant #{0} method_ref: #{1}.#{2} {3}.{4} {5} > disassembler_constantpool_name_and_type = constant #{0} name_and_type: #{1}.#{2} {3} {4} > disassembler_constantpool_utf8 = constant #{0} utf8: "{1}" >+disassembler_constantpool_methodhandle = constant #{0} method handle: {1} #{2} >+disassembler_constantpool_methodtype = constant #{0} method type: #{1} {2} >+disassembler_constantpool_invokedynamic = constant #{0} invoke dynamic: #{1} #{2} {3} {4} > disassembler_annotationdefaultheader = Annotation Default:\ > disassembler_annotationdefaultvalue= {0} (constant type) > disassembler_annotationenumvalue = {2}.{3}(enum type #{0}.#{1}) >@@ -323,6 +329,15 @@ > disassembler_frame_chop=[pc: {0}, chop {1} local(s)] > disassembler_frame_same_frame_extended=[pc: {0}, same_extended] > disassembler_frame_append=[pc: {0}, append: {1}] >+disassembler_method_type_ref_getfield = getfield ({0}) >+disassembler_method_type_ref_putfield = putfield ({0}) >+disassembler_method_type_ref_getstatic = getstatic ({0}) >+disassembler_method_type_ref_putstatic = putstatic ({0}) >+disassembler_method_type_ref_invokestatic = invokestatic ({0}) >+disassembler_method_type_ref_invokevirtual = invokevirtual ({0}) >+disassembler_method_type_ref_invokeinterface = invokeinterface ({0}) >+disassembler_method_type_ref_invokespecial = invokespecial ({0}) >+disassembler_method_type_ref_newinvokespecial = newinvokespecial ({0}) > # {0} = offset delta > # {1} = number of locals > # {2} = locals >@@ -358,7 +373,7 @@ > classformat_iinc = {0} {1} {2}{3} > classformat_invokespecial ={0} {2} [{1}] > classformat_invokeinterface ={0} {3} [{1}] [nargs: {2}] >-classformat_invokedynamic={0} {2} [{1}] >+classformat_invokedynamic={0} {2} {3} [{1}] > classformat_invokestatic ={0} {2} [{1}] > classformat_invokevirtual ={0} {2} [{1}] > classformat_getfield ={0} {2}.{3} : {4} [{1}] >diff --git a/org.eclipse.jdt.core/plugin.xml b/org.eclipse.jdt.core/plugin.xml >index 3784256..5d69788 100644 >--- a/org.eclipse.jdt.core/plugin.xml >+++ b/org.eclipse.jdt.core/plugin.xml >@@ -1,7 +1,7 @@ > <?xml version="1.0" encoding="UTF-8"?> > <?eclipse version="3.0"?> > <!-- >- Copyright (c) 2004, 2010 IBM Corporation and others. >+ Copyright (c) 2004, 2011 IBM Corporation 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 >@@ -158,6 +158,11 @@ > class="org.eclipse.jdt.core.CheckDebugAttributes" > library="jdtCompilerAdapter.jar"> > </antTask> >+ <antTask >+ name="eclipse.buildJarIndex" >+ class="org.eclipse.jdt.core.BuildJarIndex" >+ library="jdtCompilerAdapter.jar"> >+ </antTask> > </extension> > > <!-- =================================================================================== --> >@@ -196,6 +201,17 @@ > </extension> > > <!-- =================================================================================== --> >+<!-- Extension: Java Generate Indexer --> >+<!-- =================================================================================== --> >+<extension >+ id="JavaIndexer" >+ point="org.eclipse.core.runtime.applications"> >+ <application> >+ <run class="org.eclipse.jdt.core.index.JavaIndexerApplication" /> >+ </application> >+</extension> >+ >+<!-- =================================================================================== --> > <!-- Extension: Java Content Types --> > <!-- =================================================================================== --> > <extension point="org.eclipse.core.contenttype.contentTypes"> >diff --git a/org.eclipse.jdt.core/scripts/exportplugin.xml b/org.eclipse.jdt.core/scripts/exportplugin.xml >index f85d898..0caf4af 100644 >--- a/org.eclipse.jdt.core/scripts/exportplugin.xml >+++ b/org.eclipse.jdt.core/scripts/exportplugin.xml >@@ -1,7 +1,7 @@ > <?xml version="1.0" encoding="UTF-8"?> > > <!-- >- Copyright (c) 2007, 2011 IBM Corporation and others. >+ Copyright (c) 2007, 2012 IBM Corporation 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 >@@ -12,26 +12,26 @@ > --> > > <!-- build script to create a plugin from ${plugin} --> >-<project name="${plugin}" default="export plug-in [_3.8.0]" basedir=".."> >-<target name="export plug-in [_3.8.0]"> >+<project name="${plugin}" default="export plug-in [_3.8.1]" basedir=".."> >+<target name="export plug-in [_3.8.1]"> > <tstamp/> > <property name="qualifier" value="z${DSTAMP}-${TSTAMP}" /> > <antcall target="zz_internal_export"> >- <param name="jdt_core_version" value="3.8.0"/> >+ <param name="jdt_core_version" value="3.8.1"/> > </antcall> > </target> >-<target name="export plug-in [_3.8.0.qualifier] (binary only)"> >+<target name="export plug-in [_3.8.1.qualifier] (binary only)"> > <tstamp/> > <property name="qualifier" value="z${DSTAMP}-${TSTAMP}" /> > <antcall target="zz_internal_export_binary_only"> >- <param name="jdt_core_version" value="3.8.0.${qualifier}"/> >+ <param name="jdt_core_version" value="3.8.1.${qualifier}"/> > </antcall> > </target> >-<target name="export plug-in [_3.8.0.qualifier] (with sources)"> >+<target name="export plug-in [_3.8.1.qualifier] (with sources)"> > <tstamp/> > <property name="qualifier" value="z${DSTAMP}-${TSTAMP}" /> > <antcall target="zz_internal_export"> >- <param name="jdt_core_version" value="3.8.0.${qualifier}"/> >+ <param name="jdt_core_version" value="3.8.1.${qualifier}"/> > </antcall> > </target> > >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/JavaIndexer.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/JavaIndexer.java >new file mode 100644 >index 0000000..4fa991a >--- /dev/null >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/JavaIndexer.java >@@ -0,0 +1,42 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 IBM Corporation 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.core.index; >+ >+import java.io.IOException; >+ >+import org.eclipse.jdt.core.search.SearchEngine; >+import org.eclipse.jdt.internal.core.search.indexing.DefaultJavaIndexer; >+ >+/** >+ * {@link JavaIndexer} provides functionality to generate index files which can be used by the JDT {@link SearchEngine}. >+ * The generated index files can be used as a classpath attribute for the particular classpath entry. >+ * >+ * <p> The search engine indexes all the elements referred in the classpath entries of the project into >+ * index files. These index files are used to search the elements faster. Indexing for bigger jars could >+ * take some time. To avoid this time, one can generate the index file and specify it when the jar is added >+ * to the classpath of the project. </p> >+ * >+ * @since 3.8 >+ */ >+public final class JavaIndexer { >+ >+ /** >+ * Generates the index file for the specified jar. >+ * @param pathToJar The full path to the jar that needs to be indexed >+ * @param pathToIndexFile The full path to the index file that needs to be generated >+ * @throws IOException if the jar is not found or could not write into the index file >+ * @since 3.8 >+ */ >+ public static void generateIndexForJar(String pathToJar, String pathToIndexFile) throws IOException { >+ new DefaultJavaIndexer().generateIndexForJar(pathToJar, pathToIndexFile); >+ } >+ >+} >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/JavaIndexerApplication.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/JavaIndexerApplication.java >new file mode 100644 >index 0000000..7aae18a >--- /dev/null >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/JavaIndexerApplication.java >@@ -0,0 +1,158 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 IBM Corporation 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.core.index; >+ >+import java.io.File; >+import java.io.IOException; >+import java.text.MessageFormat; >+import java.util.ArrayList; >+ >+import org.eclipse.equinox.app.IApplication; >+import org.eclipse.equinox.app.IApplicationContext; >+import org.eclipse.osgi.util.NLS; >+ >+/** >+ * Implements an Eclipse Application for {@link org.eclipse.jdt.core.index.JavaIndexer}. >+ * >+ * <p> >+ * On MacOS, when invoked using the Eclipse executable, the "user.dir" property is set to the folder in which the >+ * eclipse.ini file is located. This makes it harder to use relative paths to point to the files to be jar'd or to >+ * the index file that is generated. >+ * </p> >+ * >+ * >+ * @since 3.8 >+ * @noinstantiate This class is not intended to be instantiated by clients. >+ * @noextend This class is not intended to be subclassed by clients. >+ */ >+public class JavaIndexerApplication implements IApplication { >+ >+ private final static class Messages extends NLS { >+ private static final String MESSAGES_NAME = "org.eclipse.jdt.core.index.messages";//$NON-NLS-1$ >+ >+ public static String CommandLineProcessing; >+ public static String CommandLineUsage; >+ public static String CommandLineOnlyOneOutputError; >+ public static String CommandLineOutputTakesArgs; >+ public static String CommandLineOnlyOneJarError; >+ public static String CommandLineJarNotSpecified; >+ public static String CommandLineIndexFileNotSpecified; >+ public static String CaughtException; >+ public static String CommandLineJarFileNotExist; >+ >+ static { >+ NLS.initializeMessages(MESSAGES_NAME, Messages.class); >+ } >+ >+ public static String bind(String message) { >+ return bind(message, null); >+ } >+ >+ public static String bind(String message, Object binding) { >+ return bind(message, new Object[] { binding }); >+ } >+ >+ public static String bind(String message, Object binding1, Object binding2) { >+ return bind(message, new Object[] { binding1, binding2 }); >+ } >+ >+ public static String bind(String message, Object[] bindings) { >+ return MessageFormat.format(message, bindings); >+ } >+ } >+ >+ private String jarToIndex; >+ private String indexFile; >+ private boolean verbose = false; >+ private static final String PDE_LAUNCH = "-pdelaunch"; //$NON-NLS-1$ >+ private static final String ARG_HELP = "-help"; //$NON-NLS-1$ >+ private static final String ARG_VERBOSE = "-verbose"; //$NON-NLS-1$ >+ private static final String ARG_OUTPUT = "-output"; //$NON-NLS-1$ >+ >+ private void displayHelp() { >+ System.out.println(Messages.bind(Messages.CommandLineUsage)); >+ } >+ >+ private void displayError(String message) { >+ System.out.println(message); >+ System.out.println(); >+ displayHelp(); >+ } >+ >+ private boolean processCommandLine(String[] argsArray) { >+ ArrayList args = new ArrayList(); >+ for (int i = 0, max = argsArray.length; i < max; i++) { >+ args.add(argsArray[i]); >+ } >+ int index = 0; >+ final int argCount = argsArray.length; >+ >+ loop: while (index < argCount) { >+ String currentArg = argsArray[index++]; >+ if (PDE_LAUNCH.equals(currentArg)) { >+ continue loop; >+ } else if (ARG_HELP.equals(currentArg)) { >+ displayHelp(); >+ return false; >+ } else if (ARG_VERBOSE.equals(currentArg)) { >+ this.verbose = true; >+ continue loop; >+ } else if (ARG_OUTPUT.equals(currentArg)) { >+ if (this.indexFile != null) { >+ displayError(Messages.bind(Messages.CommandLineOnlyOneOutputError)); >+ return false; >+ } else if (index == argCount) { >+ displayError(Messages.bind(Messages.CommandLineOutputTakesArgs)); >+ return false; >+ } >+ this.indexFile = argsArray[index++]; >+ } else { >+ if (this.jarToIndex != null) { >+ displayError(Messages.bind(Messages.CommandLineOnlyOneJarError)); >+ return false; >+ } >+ this.jarToIndex = currentArg; >+ } >+ } >+ return true; >+ } >+ >+ public Object start(IApplicationContext context) throws Exception { >+ boolean execute = processCommandLine((String[]) context.getArguments().get(IApplicationContext.APPLICATION_ARGS)); >+ if (execute) { >+ if (this.jarToIndex != null && this.indexFile != null) { >+ File f = new File(this.jarToIndex); >+ if (f.exists()) { >+ if (this.verbose) { >+ System.out.println(Messages.bind(Messages.CommandLineProcessing, this.indexFile, this.jarToIndex)); >+ } >+ try { >+ JavaIndexer.generateIndexForJar(this.jarToIndex, this.indexFile); >+ } catch (IOException e) { >+ System.out.println(Messages.bind(Messages.CaughtException, "IOException", e.getLocalizedMessage())); //$NON-NLS-1$ >+ } >+ } else { >+ System.out.println(Messages.bind(Messages.CommandLineJarFileNotExist, this.jarToIndex)); >+ } >+ } else if (this.jarToIndex == null) { >+ System.out.println(Messages.bind(Messages.CommandLineJarNotSpecified)); >+ } else if (this.indexFile == null) { >+ System.out.println(Messages.bind(Messages.CommandLineIndexFileNotSpecified)); >+ } >+ } >+ return IApplication.EXIT_OK; >+ } >+ >+ public void stop() { >+ // do nothing >+ } >+ >+} >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/messages.properties b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/messages.properties >new file mode 100644 >index 0000000..139ce10 >--- /dev/null >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/messages.properties >@@ -0,0 +1,29 @@ >+############################################################################### >+# Copyright (c) 2000, 2006 IBM Corporation 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: >+# IBM Corporation - initial API and implementation >+############################################################################### >+CommandLineUsage=Usage: eclipse -application org.eclipse.jdt.core.JavaIndexer [ OPTIONS ] -output <indexFile> <jarfile>\n\ >+\n\ >+\ -output <indexFile> Path to the index file to be generated.\n\ >+\ >+\ <jarfile> Path to the jar for which index needs to be generated.\n\ >+\ >+\n\ >+\ OPTIONS:\n\ >+\n\ >+\ -help Display this message.\n\ >+\ -verbose Be verbose about the job. >+CommandLineProcessing=Generating index {0} for the jar {1}. >+CommandLineOnlyOneOutputError=Only one output needs to be specified. >+CommandLineOutputTakesArgs=-output should be followed by the path to the index file. >+CommandLineOnlyOneJarError=Only one jar file needs to be specified. >+CommandLineJarNotSpecified=No jar file is specified. >+CommandLineIndexFileNotSpecified=No index file is specified. >+CaughtException=Exception {0} - {1}. >+CommandLineJarFileNotExist={0} does not exist. >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/package.html b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/package.html >new file mode 100644 >index 0000000..ea16568 >--- /dev/null >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/package.html >@@ -0,0 +1,19 @@ >+<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> >+<html> >+<head> >+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> >+ <meta name="Author" content="IBM"> >+ <meta name="GENERATOR" content="Mozilla/4.73 [en] (Windows NT 5.0; U) [Netscape]"> >+ <title>Package-level Javadoc</title> >+</head> >+<body> >+Provides support for generating indexes that can be used by the JDT search engine. >+<h2> >+Package Specification</h2> >+This package provides support for generating indexes that can be used by the search engine. The search engine >+indexes all the elements referred in the classpath entries of the project into >+index files. These index files are used to search the elements faster. Indexing for bigger jars could >+take some time. To avoid this time, one can generate the index file and specify it when the jar is added >+to the classpath of the project. >+</body> >+</html> >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchParticipant.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchParticipant.java >index 4e3f6c4..2a87b52 100644 >--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchParticipant.java >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchParticipant.java >@@ -14,6 +14,8 @@ > import org.eclipse.core.runtime.*; > import org.eclipse.jdt.internal.core.JavaModel; > import org.eclipse.jdt.internal.core.JavaModelManager; >+import org.eclipse.jdt.internal.core.index.FileIndexLocation; >+import org.eclipse.jdt.internal.core.index.IndexLocation; > import org.eclipse.jdt.internal.core.search.indexing.IndexManager; > > /** >@@ -192,9 +194,9 @@ > * </p> > * > * @param document the document to index >- * @param indexLocation the location on the file system of the index >+ * @param indexPath the location on the file system of the index > */ >- public final void scheduleDocumentIndexing(SearchDocument document, IPath indexLocation) { >+ public final void scheduleDocumentIndexing(SearchDocument document, IPath indexPath) { > IPath documentPath = new Path(document.getPath()); > Object file = JavaModel.getTarget(documentPath, true); > IPath containerPath = documentPath; >@@ -205,11 +207,13 @@ > } > IndexManager manager = JavaModelManager.getIndexManager(); > // TODO (frederic) should not have to create index manually, should expose API that recreates index instead >+ IndexLocation indexLocation; >+ indexLocation = new FileIndexLocation(indexPath.toFile(), true); > manager.ensureIndexExists(indexLocation, containerPath); > manager.scheduleDocumentIndexing(document, containerPath, indexLocation, this); >- if (!indexLocation.equals(this.lastIndexLocation)) { >- manager.updateParticipant(indexLocation, containerPath); >- this.lastIndexLocation = indexLocation; >+ if (!indexPath.equals(this.lastIndexLocation)) { >+ manager.updateParticipant(indexPath, containerPath); >+ this.lastIndexLocation = indexPath; > } > } > >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java >index 7644036..8e09289 100644 >--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java >@@ -23,7 +23,7 @@ > > public class DiskIndex { > >-File indexFile; >+IndexLocation indexLocation; > > private int headerInfoOffset; > private int numberOfChunks; >@@ -82,12 +82,7 @@ > } > > >-DiskIndex(String fileName) { >- if (fileName == null) >- throw new java.lang.IllegalArgumentException(); >- this.indexFile = new File(fileName); >- >- // clear cached items >+DiskIndex() { > this.headerInfoOffset = -1; > this.numberOfChunks = -1; > this.sizeOfLastChunk = -1; >@@ -99,6 +94,13 @@ > this.cachedCategoryName = null; > this.categoryOffsets = null; > this.categoryEnds = null; >+} >+DiskIndex(IndexLocation location) throws IOException { >+ this(); >+ if (location == null) { >+ throw new IllegalArgumentException(); >+ } >+ this.indexLocation = location; > } > SimpleSet addDocumentNames(String substring, MemoryIndex memoryIndex) throws IOException { > // must skip over documents which have been added/changed/deleted in the memory index >@@ -230,7 +232,7 @@ > private void cacheDocumentNames() throws IOException { > // will need all document names so get them now > this.cachedChunks = new String[this.numberOfChunks][]; >- FileInputStream stream = new FileInputStream(this.indexFile); >+ InputStream stream = this.indexLocation.getInputStream(); > try { > if (this.numberOfChunks > 5) BUFFER_READ_SIZE <<= 1; > int offset = this.chunkOffsets[0]; >@@ -370,9 +372,12 @@ > } > } > void initialize(boolean reuseExistingFile) throws IOException { >- if (this.indexFile.exists()) { >+ if (this.indexLocation.exists()) { > if (reuseExistingFile) { >- FileInputStream stream = new FileInputStream(this.indexFile); >+ InputStream stream = this.indexLocation.getInputStream(); >+ if (stream == null) { >+ throw new IOException("Failed to use the index file"); //$NON-NLS-1$ >+ } > this.streamBuffer = new byte[BUFFER_READ_SIZE]; > this.bufferIndex = 0; > this.bufferEnd = stream.read(this.streamBuffer, 0, 128); >@@ -393,14 +398,14 @@ > } > return; > } >- if (!this.indexFile.delete()) { >+ if (!this.indexLocation.delete()) { > if (DEBUG) >- System.out.println("initialize - Failed to delete index " + this.indexFile); //$NON-NLS-1$ >- throw new IOException("Failed to delete index " + this.indexFile); //$NON-NLS-1$ >+ System.out.println("initialize - Failed to delete index " + this.indexLocation); //$NON-NLS-1$ >+ throw new IOException("Failed to delete index " + this.indexLocation); //$NON-NLS-1$ > } > } >- if (this.indexFile.createNewFile()) { >- FileOutputStream stream = new FileOutputStream(this.indexFile, false); >+ if (this.indexLocation.createNewFile()) { >+ FileOutputStream stream = new FileOutputStream(this.indexLocation.getIndexFile(), false); > try { > this.streamBuffer = new byte[BUFFER_READ_SIZE]; > this.bufferIndex = 0; >@@ -416,18 +421,18 @@ > } > } else { > if (DEBUG) >- System.out.println("initialize - Failed to create new index " + this.indexFile); //$NON-NLS-1$ >- throw new IOException("Failed to create new index " + this.indexFile); //$NON-NLS-1$ >+ System.out.println("initialize - Failed to create new index " + this.indexLocation); //$NON-NLS-1$ >+ throw new IOException("Failed to create new index " + this.indexLocation); //$NON-NLS-1$ > } > } > private void initializeFrom(DiskIndex diskIndex, File newIndexFile) throws IOException { > if (newIndexFile.exists() && !newIndexFile.delete()) { // delete the temporary index file > if (DEBUG) >- System.out.println("initializeFrom - Failed to delete temp index " + this.indexFile); //$NON-NLS-1$ >+ System.out.println("initializeFrom - Failed to delete temp index " + this.indexLocation); //$NON-NLS-1$ > } else if (!newIndexFile.createNewFile()) { > if (DEBUG) >- System.out.println("initializeFrom - Failed to create temp index " + this.indexFile); //$NON-NLS-1$ >- throw new IOException("Failed to create temp index " + this.indexFile); //$NON-NLS-1$ >+ System.out.println("initializeFrom - Failed to create temp index " + this.indexLocation); //$NON-NLS-1$ >+ throw new IOException("Failed to create temp index " + this.indexLocation); //$NON-NLS-1$ > } > > int size = diskIndex.categoryOffsets == null ? 8 : diskIndex.categoryOffsets.elementSize; >@@ -500,6 +505,9 @@ > DiskIndex mergeWith(MemoryIndex memoryIndex) throws IOException { > // assume write lock is held > // compute & write out new docNames >+ if (this.indexLocation == null) { >+ throw new IOException("Pre-built index file not writeable"); //$NON-NLS-1$ >+ } > String[] docNames = readAllDocumentNames(); > int previousLength = docNames.length; > int[] positions = new int[previousLength]; // keeps track of the position of each document in the new sorted docNames >@@ -509,15 +517,16 @@ > if (previousLength == 0) return this; // nothing to do... memory index contained deleted documents that had never been saved > > // index is now empty since all the saved documents were removed >- DiskIndex newDiskIndex = new DiskIndex(this.indexFile.getPath()); >+ DiskIndex newDiskIndex = new DiskIndex(this.indexLocation); > newDiskIndex.initialize(false); > return newDiskIndex; > } >- >- DiskIndex newDiskIndex = new DiskIndex(this.indexFile.getPath() + ".tmp"); //$NON-NLS-1$ >+ File oldIndexFile = this.indexLocation.getIndexFile(); >+ DiskIndex newDiskIndex = new DiskIndex(new FileIndexLocation(new File(oldIndexFile.getPath() + ".tmp"))); //$NON-NLS-1$ >+ File newIndexFile = newDiskIndex.indexLocation.getIndexFile(); > try { >- newDiskIndex.initializeFrom(this, newDiskIndex.indexFile); >- FileOutputStream stream = new FileOutputStream(newDiskIndex.indexFile, false); >+ newDiskIndex.initializeFrom(this, newIndexFile); >+ FileOutputStream stream = new FileOutputStream(newIndexFile, false); > int offsetToHeader = -1; > try { > newDiskIndex.writeAllDocumentNames(docNames, stream); >@@ -549,31 +558,31 @@ > newDiskIndex.writeOffsetToHeader(offsetToHeader); > > // rename file by deleting previous index file & renaming temp one >- if (this.indexFile.exists() && !this.indexFile.delete()) { >+ if (oldIndexFile.exists() && !oldIndexFile.delete()) { > if (DEBUG) >- System.out.println("mergeWith - Failed to delete " + this.indexFile); //$NON-NLS-1$ >- throw new IOException("Failed to delete index file " + this.indexFile); //$NON-NLS-1$ >+ System.out.println("mergeWith - Failed to delete " + this.indexLocation); //$NON-NLS-1$ >+ throw new IOException("Failed to delete index file " + this.indexLocation); //$NON-NLS-1$ > } >- if (!newDiskIndex.indexFile.renameTo(this.indexFile)) { >+ if (!newIndexFile.renameTo(oldIndexFile)) { > if (DEBUG) >- System.out.println("mergeWith - Failed to rename " + this.indexFile); //$NON-NLS-1$ >- throw new IOException("Failed to rename index file " + this.indexFile); //$NON-NLS-1$ >+ System.out.println("mergeWith - Failed to rename " + this.indexLocation); //$NON-NLS-1$ >+ throw new IOException("Failed to rename index file " + this.indexLocation); //$NON-NLS-1$ > } > } catch (IOException e) { >- if (newDiskIndex.indexFile.exists() && !newDiskIndex.indexFile.delete()) >+ if (newIndexFile.exists() && !newIndexFile.delete()) > if (DEBUG) >- System.out.println("mergeWith - Failed to delete temp index " + newDiskIndex.indexFile); //$NON-NLS-1$ >+ System.out.println("mergeWith - Failed to delete temp index " + newDiskIndex.indexLocation); //$NON-NLS-1$ > throw e; > } > >- newDiskIndex.indexFile = this.indexFile; >+ newDiskIndex.indexLocation = this.indexLocation; > return newDiskIndex; > } > private synchronized String[] readAllDocumentNames() throws IOException { > if (this.numberOfChunks <= 0) > return CharOperation.NO_STRINGS; > >- FileInputStream stream = new FileInputStream(this.indexFile); >+ InputStream stream = this.indexLocation.getInputStream(); > try { > int offset = this.chunkOffsets[0]; > stream.skip(offset); >@@ -612,7 +621,7 @@ > } > } > >- FileInputStream stream = new FileInputStream(this.indexFile); >+ InputStream stream = this.indexLocation.getInputStream(); > HashtableOfObject categoryTable = null; > char[][] matchingWords = null; > int count = 0; >@@ -626,7 +635,7 @@ > try { > if (size < 0) { // DEBUG > System.err.println("-------------------- DEBUG --------------------"); //$NON-NLS-1$ >- System.err.println("file = "+this.indexFile); //$NON-NLS-1$ >+ System.err.println("file = "+this.indexLocation); //$NON-NLS-1$ > System.err.println("offset = "+offset); //$NON-NLS-1$ > System.err.println("size = "+size); //$NON-NLS-1$ > System.err.println("-------------------- END --------------------"); //$NON-NLS-1$ >@@ -636,7 +645,7 @@ > // DEBUG > oom.printStackTrace(); > System.err.println("-------------------- DEBUG --------------------"); //$NON-NLS-1$ >- System.err.println("file = "+this.indexFile); //$NON-NLS-1$ >+ System.err.println("file = "+this.indexLocation); //$NON-NLS-1$ > System.err.println("offset = "+offset); //$NON-NLS-1$ > System.err.println("size = "+size); //$NON-NLS-1$ > System.err.println("-------------------- END --------------------"); //$NON-NLS-1$ >@@ -678,7 +687,7 @@ > } > > if (matchingWords != null && count > 0) { >- stream = new FileInputStream(this.indexFile); >+ stream = this.indexLocation.getInputStream(); > try { > stream.skip(firstOffset); > this.bufferIndex = 0; >@@ -696,7 +705,7 @@ > this.streamBuffer = null; > return categoryTable; > } >-private void readChunk(String[] docNames, FileInputStream stream, int index, int size) throws IOException { >+private void readChunk(String[] docNames, InputStream stream, int index, int size) throws IOException { > String current = new String(readStreamChars(stream)); > docNames[index++] = current; > for (int i = 1; i < size; i++) { >@@ -734,7 +743,7 @@ > throw new IllegalArgumentException(); > this.streamBuffer = new byte[numberOfBytes]; > this.bufferIndex = 0; >- FileInputStream file = new FileInputStream(this.indexFile); >+ InputStream file = this.indexLocation.getInputStream(); > try { > file.skip(start); > if (file.read(this.streamBuffer, 0, numberOfBytes) != numberOfBytes) >@@ -763,7 +772,7 @@ > if (arrayOffset instanceof int[]) > return (int[]) arrayOffset; > >- FileInputStream stream = new FileInputStream(this.indexFile); >+ InputStream stream = this.indexLocation.getInputStream(); > try { > int offset = ((Integer) arrayOffset).intValue(); > stream.skip(offset); >@@ -776,19 +785,19 @@ > this.streamBuffer = null; > } > } >-private void readHeaderInfo(FileInputStream stream) throws IOException { >+private void readHeaderInfo(InputStream stream) throws IOException { > > // must be same order as writeHeaderInfo() > this.numberOfChunks = readStreamInt(stream); > this.sizeOfLastChunk = this.streamBuffer[this.bufferIndex++] & 0xFF; > this.documentReferenceSize = this.streamBuffer[this.bufferIndex++] & 0xFF; > this.separator = (char) (this.streamBuffer[this.bufferIndex++] & 0xFF); >- long fileLength = this.indexFile.length(); >- if (this.numberOfChunks > fileLength ) { >+ long length = this.indexLocation.length(); >+ if (length != -1 && this.numberOfChunks > length) { > // not an accurate check, but good enough https://bugs.eclipse.org/bugs/show_bug.cgi?id=350612 > if (DEBUG) >- System.out.println("Index file is corrupted " + this.indexFile); //$NON-NLS-1$ >- throw new IOException("Index file is corrupted " + this.indexFile); //$NON-NLS-1$ >+ System.out.println("Index file is corrupted " + this.indexLocation); //$NON-NLS-1$ >+ throw new IOException("Index file is corrupted " + this.indexLocation); //$NON-NLS-1$ > } > this.chunkOffsets = new int[this.numberOfChunks]; > for (int i = 0; i < this.numberOfChunks; i++) >@@ -799,11 +808,11 @@ > int size = readStreamInt(stream); > this.categoryOffsets = new HashtableOfIntValues(size); > this.categoryEnds = new HashtableOfIntValues(size); >- if (size > fileLength) { >+ if (length != -1 && size > length) { > // not an accurate check, but good enough https://bugs.eclipse.org/bugs/show_bug.cgi?id=350612 > if (DEBUG) >- System.out.println("Index file is corrupted " + this.indexFile); //$NON-NLS-1$ >- throw new IOException("Index file is corrupted " + this.indexFile); //$NON-NLS-1$ >+ System.out.println("Index file is corrupted " + this.indexLocation); //$NON-NLS-1$ >+ throw new IOException("Index file is corrupted " + this.indexLocation); //$NON-NLS-1$ > } > char[] previousCategory = null; > int offset = -1; >@@ -840,11 +849,13 @@ > } > } > } >-private void readStreamBuffer(FileInputStream stream) throws IOException { >+private void readStreamBuffer(InputStream stream) throws IOException { > // if we're about to read a known amount at the end of the existing buffer, but it does not completely fit > // so we need to shift the remaining bytes to be read, and fill the buffer from the stream >- if (this.bufferEnd < this.streamBuffer.length) >- return; // we're at the end of the stream - nothing left to read >+ if (this.bufferEnd < this.streamBuffer.length) { >+ if (stream.available() == 0) >+ return; // we're at the end of the stream - nothing left to read >+ } > > int bytesInBuffer = this.bufferEnd - this.bufferIndex; > if (bytesInBuffer > 0) >@@ -872,7 +883,7 @@ > * @exception UTFDataFormatException if the bytes do not represent a > * valid UTF-8 encoding of a Unicode string. > */ >-private char[] readStreamChars(FileInputStream stream) throws IOException { >+private char[] readStreamChars(InputStream stream) throws IOException { > // read chars array length > if (stream != null && this.bufferIndex + 2 >= this.bufferEnd) > readStreamBuffer(stream); >@@ -886,7 +897,7 @@ > // how many characters can be decoded without refilling the buffer? > int charsInBuffer = i + ((this.bufferEnd - this.bufferIndex) / 3); > // all the characters must already be in the buffer if we're at the end of the stream >- if (charsInBuffer > length || this.bufferEnd != this.streamBuffer.length || stream == null) >+ if (charsInBuffer > length || stream == null || (this.bufferEnd != this.streamBuffer.length && stream.available() == 0)) > charsInBuffer = length; > while (i < charsInBuffer) { > byte b = this.streamBuffer[this.bufferIndex++]; >@@ -931,7 +942,7 @@ > } > return word; > } >-private int[] readStreamDocumentArray(FileInputStream stream, int arraySize) throws IOException { >+private int[] readStreamDocumentArray(InputStream stream, int arraySize) throws IOException { > int[] indexes = new int[arraySize]; > if (arraySize == 0) return indexes; > >@@ -972,7 +983,7 @@ > } > return indexes; > } >-private int readStreamInt(FileInputStream stream) throws IOException { >+private int readStreamInt(InputStream stream) throws IOException { > if (this.bufferIndex + 4 >= this.bufferEnd) { > readStreamBuffer(stream); > } >@@ -1182,7 +1193,7 @@ > } > private void writeOffsetToHeader(int offsetToHeader) throws IOException { > if (offsetToHeader > 0) { >- RandomAccessFile file = new RandomAccessFile(this.indexFile, "rw"); //$NON-NLS-1$ >+ RandomAccessFile file = new RandomAccessFile(this.indexLocation.getIndexFile(), "rw"); //$NON-NLS-1$ > try { > file.seek(this.headerInfoOffset); // offset to position in header > file.writeInt(offsetToHeader); >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/FileIndexLocation.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/FileIndexLocation.java >new file mode 100644 >index 0000000..67fc9ae >--- /dev/null >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/FileIndexLocation.java >@@ -0,0 +1,98 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 IBM Corporation 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.internal.core.index; >+ >+import java.io.File; >+import java.io.FileInputStream; >+import java.io.IOException; >+import java.io.InputStream; >+import java.net.URL; >+ >+import org.eclipse.core.runtime.IPath; >+import org.eclipse.core.runtime.Path; >+ >+public class FileIndexLocation extends IndexLocation { >+ File indexFile; >+ >+ public FileIndexLocation(File file) { >+ super(file); >+ this.indexFile = file; >+ } >+ >+ public FileIndexLocation(URL url, File file) { >+ super(url); >+ this.indexFile = file; >+ } >+ >+ public FileIndexLocation(File file, boolean participantIndex) { >+ this(file); >+ this.participantIndex = true; >+ } >+ >+ public boolean createNewFile() throws IOException { >+ return this.indexFile.createNewFile(); >+ } >+ >+ public boolean delete() { >+ return this.indexFile.delete(); >+ } >+ >+ public boolean equals(Object other) { >+ if (!(other instanceof FileIndexLocation)) return false; >+ return this.indexFile.equals(((FileIndexLocation) other).indexFile); >+ } >+ >+ public boolean exists() { >+ return this.indexFile.exists(); >+ } >+ >+ public String fileName() { >+ return this.indexFile.getName(); >+ } >+ >+ public File getIndexFile() { >+ return this.indexFile; >+ } >+ >+ InputStream getInputStream() throws IOException { >+ return new FileInputStream(this.indexFile); >+ } >+ >+ public String getCanonicalFilePath() { >+ try { >+ return this.indexFile.getCanonicalPath(); >+ } catch (IOException e) { >+ // ignore >+ } >+ return null; >+ } >+ >+ public int hashCode() { >+ return this.indexFile.hashCode(); >+ } >+ >+ public long lastModified() { >+ return this.indexFile.lastModified(); >+ } >+ >+ public long length() { >+ return this.indexFile.length(); >+ } >+ >+ public boolean startsWith(IPath path) { >+ try { >+ return path.isPrefixOf(new Path(this.indexFile.getCanonicalPath())); >+ } catch (IOException e) { >+ return false; >+ } >+ } >+ >+} >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/Index.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/Index.java >index 3d32607..8caa73c 100644 >--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/Index.java >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/Index.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -88,12 +88,12 @@ > } > > >-public Index(String fileName, String containerPath, boolean reuseExistingFile) throws IOException { >+public Index(IndexLocation location, String containerPath, boolean reuseExistingFile) throws IOException { > this.containerPath = containerPath; > this.monitor = new ReadWriteMonitor(); > > this.memoryIndex = new MemoryIndex(); >- this.diskIndex = new DiskIndex(fileName); >+ this.diskIndex = new DiskIndex(location); > this.diskIndex.initialize(reuseExistingFile); > if (reuseExistingFile) this.separator = this.diskIndex.separator; > } >@@ -110,7 +110,13 @@ > return documentPath.substring(index + 1); > } > public File getIndexFile() { >- return this.diskIndex == null ? null : this.diskIndex.indexFile; >+ return this.diskIndex == null ? null : this.diskIndex.indexLocation.getIndexFile(); >+} >+public IndexLocation getIndexLocation() { >+ return this.diskIndex == null ? null : this.diskIndex.indexLocation; >+} >+public long getIndexLastModified() { >+ return this.diskIndex == null? -1 : this.diskIndex.indexLocation.lastModified(); > } > public boolean hasChanged() { > return this.memoryIndex.hasChanged(); >@@ -180,7 +186,7 @@ > */ > public void reset() throws IOException { > this.memoryIndex = new MemoryIndex(); >- this.diskIndex = new DiskIndex(this.diskIndex.indexFile.getCanonicalPath()); >+ this.diskIndex = new DiskIndex(this.diskIndex.indexLocation); > this.diskIndex.initialize(false/*do not reuse the index file*/); > } > public void save() throws IOException { >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/IndexLocation.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/IndexLocation.java >new file mode 100644 >index 0000000..d410f72 >--- /dev/null >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/IndexLocation.java >@@ -0,0 +1,124 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 IBM Corporation 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.internal.core.index; >+ >+import java.io.File; >+import java.io.IOException; >+import java.io.InputStream; >+ >+import java.net.MalformedURLException; >+import java.net.URL; >+ >+import org.eclipse.core.runtime.FileLocator; >+import org.eclipse.core.runtime.IPath; >+ >+/** >+ * The location of the index files are represented as {@link IndexLocation} >+ * >+ * This is an abstract class to allow different implementation for a jar entry and a file >+ * on the disk. Some of these functions could mean different for a jar entry or a file >+ * >+ */ >+public abstract class IndexLocation { >+ >+ public static IndexLocation createIndexLocation(URL url) { >+ URL localUrl; >+ try { >+ localUrl = FileLocator.resolve(url); >+ } catch (IOException e) { >+ return null; >+ } >+ if (localUrl.getProtocol().equals("file")) { //$NON-NLS-1$ >+ return new FileIndexLocation(url, new File(localUrl.getPath())); >+ } >+ return new JarIndexLocation(url, localUrl); >+ } >+ >+ private final URL url; // url of the given index location >+ >+ /** >+ * Set to true if this index location is of an index file specified >+ * by a participant through >+ * {@link org.eclipse.jdt.core.search.SearchParticipant#scheduleDocumentIndexing} >+ */ >+ protected boolean participantIndex; >+ >+ protected IndexLocation(File file) { >+ URL tempUrl = null; >+ try { >+ tempUrl = file.toURI().toURL(); >+ } catch (MalformedURLException e) { >+ // should not happen >+ } >+ this.url = tempUrl; >+ } >+ >+ public IndexLocation(URL url) { >+ this.url = url; >+ } >+ >+ /** >+ * Closes any open streams. >+ */ >+ public void close() { >+ // default nothing to do >+ } >+ >+ /** >+ * Creates a new file for the given index location >+ * @return true if the file is created >+ * @throws IOException >+ */ >+ public abstract boolean createNewFile() throws IOException; >+ >+ public abstract boolean delete(); >+ >+ public abstract boolean exists(); >+ >+ public abstract String fileName(); >+ >+ /** >+ * @return the canonical file path if the location is a file or null otherwise >+ */ >+ public abstract String getCanonicalFilePath(); >+ >+ public abstract File getIndexFile(); >+ >+ abstract InputStream getInputStream() throws IOException; >+ >+ public URL getUrl() { >+ return this.url; >+ } >+ >+ public int hashCode() { >+ return this.url.hashCode(); >+ } >+ >+ public boolean isParticipantIndex() { >+ return this.participantIndex; >+ } >+ >+ /** >+ * @return the last modified time if the location is a file or -1 otherwise >+ */ >+ public abstract long lastModified(); >+ >+ /** >+ * @return the length of the file if the location is a file or -1 otherwise >+ */ >+ public abstract long length(); >+ >+ public abstract boolean startsWith(IPath path); >+ >+ public String toString() { >+ return this.url.toString(); >+ } >+} >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/JarIndexLocation.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/JarIndexLocation.java >new file mode 100644 >index 0000000..a93a264 >--- /dev/null >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/JarIndexLocation.java >@@ -0,0 +1,108 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 IBM Corporation 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.internal.core.index; >+ >+import java.io.File; >+import java.io.IOException; >+import java.io.InputStream; >+import java.net.JarURLConnection; >+import java.net.URL; >+import java.util.jar.JarEntry; >+import java.util.jar.JarFile; >+ >+import org.eclipse.core.runtime.IPath; >+import org.eclipse.core.runtime.Path; >+ >+public class JarIndexLocation extends IndexLocation { >+ private JarFile jarFile = null; >+ private JarEntry jarEntry = null; >+ private URL localUrl; >+ >+ public JarIndexLocation(URL url, URL localUrl2) { >+ super(url); >+ this.localUrl = localUrl2; >+ } >+ >+ public boolean createNewFile() throws IOException { >+ return false; >+ } >+ >+ public void close() { >+ if (this.jarFile != null) { >+ try { >+ this.jarFile.close(); >+ } catch (IOException e) { >+ // ignore >+ } >+ this.jarFile = null; >+ } >+ } >+ >+ public boolean delete() { >+ return false; >+ } >+ >+ public boolean equals(Object other) { >+ if (!(other instanceof JarIndexLocation)) return false; >+ return this.localUrl.equals(((JarIndexLocation) other).localUrl); >+ } >+ >+ public boolean exists() { >+ try { >+ if (this.jarFile == null) { >+ JarURLConnection connection = (JarURLConnection) this.localUrl.openConnection(); >+ JarFile file = connection.getJarFile(); >+ if (file == null) >+ return false; >+ file.close(); >+ } >+ } catch (IOException e) { >+ return false; >+ } >+ return true; >+ } >+ >+ public String fileName() { >+ return null; >+ } >+ >+ public File getIndexFile() { >+ return null; >+ } >+ >+ InputStream getInputStream() throws IOException { >+ if (this.jarFile == null) { >+ JarURLConnection connection = (JarURLConnection) this.localUrl.openConnection(); >+ this.jarFile = connection.getJarFile(); >+ this.jarEntry = connection.getJarEntry(); >+ } >+ if (this.jarFile == null || this.jarEntry == null) >+ return null; >+ return this.jarFile.getInputStream(this.jarEntry); >+ } >+ >+ public String getCanonicalFilePath() { >+ return null; >+ } >+ >+ public long lastModified() { >+ return -1; >+ } >+ >+ public long length() { >+ return -1; >+ } >+ >+ public boolean startsWith(IPath path) { >+ return (path.isPrefixOf(new Path(this.localUrl.getPath()))); >+ } >+ >+} >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IndexSelector.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IndexSelector.java >index 4e584f2..20990c9 100644 >--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IndexSelector.java >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IndexSelector.java >@@ -27,6 +27,7 @@ > import org.eclipse.jdt.internal.core.JavaProject; > import org.eclipse.jdt.internal.core.builder.ReferenceCollection; > import org.eclipse.jdt.internal.core.builder.State; >+import org.eclipse.jdt.internal.core.index.IndexLocation; > import org.eclipse.jdt.internal.core.search.indexing.IndexManager; > import org.eclipse.jdt.internal.core.search.matching.MatchLocator; > import org.eclipse.jdt.internal.core.search.matching.MethodPattern; >@@ -38,7 +39,7 @@ > public class IndexSelector { > IJavaSearchScope searchScope; > SearchPattern pattern; >- IPath[] indexLocations; // cache of the keys for looking index up >+ IndexLocation[] indexLocations; // cache of the keys for looking index up > > public IndexSelector( > IJavaSearchScope searchScope, >@@ -267,10 +268,10 @@ > } > > locations.remove(null); // Ensure no nulls >- this.indexLocations = (IPath[]) locations.toArray(new IPath[locations.size()]); >+ this.indexLocations = (IndexLocation[]) locations.toArray(new IndexLocation[locations.size()]); > } > >-public IPath[] getIndexLocations() { >+public IndexLocation[] getIndexLocations() { > if (this.indexLocations == null) { > initializeIndexLocations(); > } >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchParticipant.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchParticipant.java >index 13d6820..cf970b3 100644 >--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchParticipant.java >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchParticipant.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -12,6 +12,7 @@ > > import org.eclipse.core.runtime.*; > import org.eclipse.jdt.core.search.*; >+import org.eclipse.jdt.internal.core.index.IndexLocation; > import org.eclipse.jdt.internal.core.search.indexing.BinaryIndexer; > import org.eclipse.jdt.internal.core.search.indexing.SourceIndexer; > import org.eclipse.jdt.internal.core.search.matching.MatchLocator; >@@ -98,7 +99,20 @@ > * @see org.eclipse.jdt.core.search.SearchParticipant#selectIndexes(org.eclipse.jdt.core.search.SearchQuery, org.eclipse.jdt.core.search.SearchContext) > */ > public IPath[] selectIndexes(SearchPattern pattern, IJavaSearchScope scope) { >+ IndexSelector selector = (IndexSelector) this.indexSelector.get(); >+ if (selector == null) { >+ selector = new IndexSelector(scope, pattern); >+ this.indexSelector.set(selector); >+ } >+ IndexLocation[] urls = selector.getIndexLocations(); >+ IPath[] paths = new IPath[urls.length]; >+ for (int i = 0; i < urls.length; i++) { >+ paths[i] = new Path(urls[i].getIndexFile().getPath()); >+ } >+ return paths; >+ } > >+ public IndexLocation[] selectIndexURLs(SearchPattern pattern, IJavaSearchScope scope) { > IndexSelector selector = (IndexSelector) this.indexSelector.get(); > if (selector == null) { > selector = new IndexSelector(scope, pattern); >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/PatternSearchJob.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/PatternSearchJob.java >index 459730c..c83c2f1 100644 >--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/PatternSearchJob.java >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/PatternSearchJob.java >@@ -17,7 +17,9 @@ > import org.eclipse.core.runtime.OperationCanceledException; > import org.eclipse.jdt.core.search.*; > import org.eclipse.jdt.internal.core.JavaModelManager; >+import org.eclipse.jdt.internal.core.index.FileIndexLocation; > import org.eclipse.jdt.internal.core.index.Index; >+import org.eclipse.jdt.internal.core.index.IndexLocation; > import org.eclipse.jdt.internal.core.search.indexing.ReadWriteMonitor; > import org.eclipse.jdt.internal.core.search.matching.MatchLocator; > import org.eclipse.jdt.internal.core.search.processing.IJob; >@@ -76,8 +78,19 @@ > } > public Index[] getIndexes(IProgressMonitor progressMonitor) { > // acquire the in-memory indexes on the fly >- IPath[] indexLocations = this.participant.selectIndexes(this.pattern, this.scope); >- int length = indexLocations.length; >+ IndexLocation[] indexLocations; >+ int length; >+ if (this.participant instanceof JavaSearchParticipant) { >+ indexLocations = ((JavaSearchParticipant)this.participant).selectIndexURLs(this.pattern, this.scope); >+ length = indexLocations.length; >+ } else { >+ IPath[] paths = this.participant.selectIndexes(this.pattern, this.scope); >+ length = paths.length; >+ indexLocations = new IndexLocation[paths.length]; >+ for (int i = 0, len = paths.length; i < len; i++) { >+ indexLocations[i] = new FileIndexLocation(paths[i].toFile(), true); >+ } >+ } > Index[] indexes = JavaModelManager.getIndexManager().getIndexes(indexLocations, progressMonitor); > this.areIndexesReady = indexes.length == length; > return indexes; >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJarFileToIndex.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJarFileToIndex.java >index 168904f..812c462 100644 >--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJarFileToIndex.java >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJarFileToIndex.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -34,6 +34,7 @@ > import org.eclipse.jdt.internal.compiler.util.Util; > import org.eclipse.jdt.internal.core.JavaModelManager; > import org.eclipse.jdt.internal.core.index.Index; >+import org.eclipse.jdt.internal.core.index.IndexLocation; > import org.eclipse.jdt.internal.core.search.JavaSearchDocument; > import org.eclipse.jdt.internal.core.search.processing.JobManager; > >@@ -42,14 +43,17 @@ > private static final char JAR_SEPARATOR = IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR.charAt(0); > IFile resource; > Scanner scanner; >+ private IndexLocation indexFileURL; > >- public AddJarFileToIndex(IFile resource, IndexManager manager) { >+ public AddJarFileToIndex(IFile resource, IndexLocation indexFile, IndexManager manager) { > super(resource.getFullPath(), manager); > this.resource = resource; >+ this.indexFileURL = indexFile; > } >- public AddJarFileToIndex(IPath jarPath, IndexManager manager) { >+ public AddJarFileToIndex(IPath jarPath, IndexLocation indexFile, IndexManager manager) { > // external JAR scenario - no resource > super(jarPath, manager); >+ this.indexFileURL = indexFile; > } > public boolean equals(Object o) { > if (o instanceof AddJarFileToIndex) { >@@ -70,6 +74,12 @@ > public boolean execute(IProgressMonitor progressMonitor) { > > if (this.isCancelled || progressMonitor != null && progressMonitor.isCanceled()) return true; >+ >+ if (this.indexFileURL != null) { >+ boolean added = this.manager.addIndex(this.containerPath, this.indexFileURL); >+ if (added) return true; >+ this.indexFileURL = null; >+ } > > try { > // if index is already cached, then do not perform any check >@@ -192,7 +202,11 @@ > return false; > } > index.separator = JAR_SEPARATOR; >- >+ IPath indexPath = null; >+ IndexLocation indexLocation; >+ if ((indexLocation = index.getIndexLocation()) != null) { >+ indexPath = new Path(indexLocation.getCanonicalFilePath()); >+ } > for (Enumeration e = zip.entries(); e.hasMoreElements();) { > if (this.isCancelled) { > if (JobManager.VERBOSE) >@@ -208,7 +222,7 @@ > // index only classes coming from valid packages - https://bugs.eclipse.org/bugs/show_bug.cgi?id=293861 > final byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getZipEntryByteContent(ze, zip); > JavaSearchDocument entryDocument = new JavaSearchDocument(ze, zipFilePath, classFileBytes, participant); >- this.manager.indexDocument(entryDocument, participant, index, this.containerPath); >+ this.manager.indexDocument(entryDocument, participant, index, indexPath); > } > } > this.manager.saveIndex(index); >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/BinaryIndexer.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/BinaryIndexer.java >index c242fb5..f752c34 100644 >--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/BinaryIndexer.java >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/BinaryIndexer.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -46,6 +46,9 @@ > super(document); > } > private void addBinaryStandardAnnotations(long annotationTagBits) { >+ if ((annotationTagBits & TagBits.AllStandardAnnotationsMask) == 0) { >+ return; >+ } > if ((annotationTagBits & TagBits.AnnotationTargetMASK) != 0) { > char[][] compoundName = TypeConstants.JAVA_LANG_ANNOTATION_TARGET; > addAnnotationTypeReference(compoundName[compoundName.length-1]); >@@ -83,14 +86,6 @@ > if ((annotationTagBits & TagBits.AnnotationPolymorphicSignature) != 0) { > char[][] compoundName = > TypeConstants.JAVA_LANG_INVOKE_METHODHANDLE_$_POLYMORPHICSIGNATURE; >- addAnnotationTypeReference(compoundName[compoundName.length-1]); >- } >- if ((annotationTagBits & TagBits.AnnotationPostConstruct) != 0) { >- char[][] compoundName = TypeConstants.JAVAX_ANNOTATION_POSTCONSTRUCT; >- addAnnotationTypeReference(compoundName[compoundName.length-1]); >- } >- if ((annotationTagBits & TagBits.AnnotationPreDestroy) != 0) { >- char[][] compoundName = TypeConstants.JAVAX_ANNOTATION_PREDESTROY; > addAnnotationTypeReference(compoundName[compoundName.length-1]); > } > } >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/DefaultJavaIndexer.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/DefaultJavaIndexer.java >new file mode 100644 >index 0000000..a548c45 >--- /dev/null >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/DefaultJavaIndexer.java >@@ -0,0 +1,61 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 IBM Corporation 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.internal.core.search.indexing; >+ >+import java.io.File; >+import java.io.FileNotFoundException; >+import java.io.IOException; >+import java.util.Enumeration; >+import java.util.zip.ZipEntry; >+import java.util.zip.ZipFile; >+ >+import org.eclipse.core.runtime.Path; >+import org.eclipse.jdt.core.search.IJavaSearchScope; >+import org.eclipse.jdt.core.search.SearchEngine; >+import org.eclipse.jdt.core.search.SearchParticipant; >+import org.eclipse.jdt.internal.compiler.util.Util; >+import org.eclipse.jdt.internal.core.index.FileIndexLocation; >+import org.eclipse.jdt.internal.core.index.Index; >+import org.eclipse.jdt.internal.core.index.IndexLocation; >+import org.eclipse.jdt.internal.core.search.JavaSearchDocument; >+ >+public class DefaultJavaIndexer { >+ private static final char JAR_SEPARATOR = IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR.charAt(0); >+ >+ public void generateIndexForJar(String pathToJar, String pathToIndexFile) throws IOException { >+ File f = new File(pathToJar); >+ if (!f.exists()) { >+ throw new FileNotFoundException(pathToJar + " not found"); //$NON-NLS-1$ >+ } >+ IndexLocation indexLocation = new FileIndexLocation(new File(pathToIndexFile)); >+ Index index = new Index(indexLocation, pathToJar, false /*reuse index file*/); >+ SearchParticipant participant = SearchEngine.getDefaultSearchParticipant(); >+ index.separator = JAR_SEPARATOR; >+ ZipFile zip = new ZipFile(pathToJar); >+ try { >+ for (Enumeration e = zip.entries(); e.hasMoreElements();) { >+ // iterate each entry to index it >+ ZipEntry ze = (ZipEntry) e.nextElement(); >+ String zipEntryName = ze.getName(); >+ if (Util.isClassFileName(zipEntryName)) { >+ final byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getZipEntryByteContent(ze, zip); >+ JavaSearchDocument entryDocument = new JavaSearchDocument(ze, new Path(pathToJar), classFileBytes, participant); >+ entryDocument.setIndex(index); >+ new BinaryIndexer(entryDocument).indexDocument(); >+ } >+ } >+ index.save(); >+ } finally { >+ zip.close(); >+ } >+ return; >+ } >+} >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexAllProject.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexAllProject.java >index 4313621..96aa904 100644 >--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexAllProject.java >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexAllProject.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2011 IBM Corporation 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 >@@ -77,7 +77,7 @@ > if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY && entry.getPath().equals(projectPath)) { > // the project is also a library folder (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=89815) > // ensure a job exists to index it as a binary folder >- this.manager.indexLibrary(projectPath, this.project); >+ this.manager.indexLibrary(projectPath, this.project, ((ClasspathEntry)entry).getLibraryIndexLocation()); > return true; > } > } >@@ -107,7 +107,7 @@ > for (int i = 0; i < max; i++) > indexedFileNames.put(paths[i], DELETED); > } >- final long indexLastModified = max == 0 ? 0L : index.getIndexFile().lastModified(); >+ final long indexLastModified = max == 0 ? 0L : index.getIndexLastModified(); > > IWorkspaceRoot root = this.project.getWorkspace().getRoot(); > for (int i = 0; i < sourceEntriesNumber; i++) { >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexBinaryFolder.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexBinaryFolder.java >index 7bb90f9..b06e0df 100644 >--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexBinaryFolder.java >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexBinaryFolder.java >@@ -80,7 +80,7 @@ > for (int i = 0; i < max; i++) { > indexedFileNames.put(paths[i], DELETED); > } >- final long indexLastModified = index.getIndexFile().lastModified(); >+ final long indexLastModified = index.getIndexLastModified(); > this.folder.accept( > new IResourceProxyVisitor() { > public boolean visit(IResourceProxy proxy) throws CoreException { >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java >index f08c249..d130e0f 100644 >--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -11,6 +11,7 @@ > package org.eclipse.jdt.internal.core.search.indexing; > > import java.io.*; >+import java.net.URL; > import java.util.*; > import java.util.zip.CRC32; > >@@ -52,6 +53,7 @@ > /* can only replace a current state if its less than the new one */ > // key = indexLocation path, value = index state integer > private SimpleLookupTable indexStates = null; >+ private File indexNamesMapFile = new File(getSavedIndexesDirectory(), "indexNamesMap.txt"); //$NON-NLS-1$ > private File savedIndexNamesFile = new File(getSavedIndexesDirectory(), "savedIndexNames.txt"); //$NON-NLS-1$ > private File participantIndexNamesFile = new File(getSavedIndexesDirectory(), "participantsIndexNames.txt"); //$NON-NLS-1$ > private boolean javaLikeNamesChanged = true; >@@ -59,6 +61,7 @@ > public static final Integer UPDATING_STATE = new Integer(1); > public static final Integer UNKNOWN_STATE = new Integer(2); > public static final Integer REBUILDING_STATE = new Integer(3); >+ public static final Integer REUSE_STATE = new Integer(4); > > // search participants who register indexes with the index manager > private SimpleLookupTable participantsContainers = null; >@@ -70,10 +73,10 @@ > public synchronized void aboutToUpdateIndex(IPath containerPath, Integer newIndexState) { > // newIndexState is either UPDATING_STATE or REBUILDING_STATE > // must tag the index as inconsistent, in case we exit before the update job is started >- IPath indexLocation = computeIndexLocation(containerPath); >+ IndexLocation indexLocation = computeIndexLocation(containerPath); > Object state = getIndexStates().get(indexLocation); > Integer currentIndexState = state == null ? UNKNOWN_STATE : (Integer) state; >- if (currentIndexState.equals(REBUILDING_STATE)) return; // already rebuilding the index >+ if (currentIndexState.compareTo(REBUILDING_STATE) >= 0) return; // already rebuilding the index > > int compare = newIndexState.compareTo(currentIndexState); > if (compare > 0) { >@@ -92,7 +95,7 @@ > if (JavaCore.getPlugin() == null) return; > SearchParticipant participant = SearchEngine.getDefaultSearchParticipant(); > SearchDocument document = participant.getDocument(resource.getFullPath().toString()); >- IPath indexLocation = computeIndexLocation(containerPath); >+ IndexLocation indexLocation = computeIndexLocation(containerPath); > scheduleDocumentIndexing(document, containerPath, indexLocation, participant); > } > /** >@@ -104,7 +107,7 @@ > SearchParticipant participant = SearchEngine.getDefaultSearchParticipant(); > SearchDocument document = participant.getDocument(resource.getFullPath().toString()); > document.setParser(parser); >- IPath indexLocation = computeIndexLocation(containerPath); >+ IndexLocation indexLocation = computeIndexLocation(containerPath); > scheduleDocumentIndexing(document, containerPath, indexLocation, participant); > } > /* >@@ -116,17 +119,17 @@ > PatternSearchJob job = new PatternSearchJob(null, SearchEngine.getDefaultSearchParticipant(), scope, null); > Index[] selectedIndexes = job.getIndexes(null); > for (int i = 0, l = selectedIndexes.length; i < l; i++) { >- String path = selectedIndexes[i].getIndexFile().getAbsolutePath(); >- knownPaths.add(path); >+ IndexLocation IndexLocation = selectedIndexes[i].getIndexLocation(); >+ knownPaths.add(IndexLocation); > } > > if (this.indexStates != null) { > Object[] keys = this.indexStates.keyTable; >- IPath[] locations = new IPath[this.indexStates.elementSize]; >+ IndexLocation[] locations = new IndexLocation[this.indexStates.elementSize]; > int count = 0; > for (int i = 0, l = keys.length; i < l; i++) { >- IPath key = (IPath) keys[i]; >- if (key != null && !knownPaths.includes(key.toOSString())) >+ IndexLocation key = (IndexLocation) keys[i]; >+ if (key != null && !knownPaths.includes(key)) > locations[count++] = key; > } > if (count > 0) >@@ -134,8 +137,8 @@ > } > deleteIndexFiles(knownPaths); > } >-public synchronized IPath computeIndexLocation(IPath containerPath) { >- IPath indexLocation = (IPath) this.indexLocations.get(containerPath); >+public synchronized IndexLocation computeIndexLocation(IPath containerPath) { >+ IndexLocation indexLocation = (IndexLocation) this.indexLocations.get(containerPath); > if (indexLocation == null) { > String pathString = containerPath.toOSString(); > CRC32 checksumCalculator = new CRC32(); >@@ -144,7 +147,7 @@ > if (VERBOSE) > Util.verbose("-> index name for " + pathString + " is " + fileName); //$NON-NLS-1$ //$NON-NLS-2$ > // to share the indexLocation between the indexLocations and indexStates tables, get the key from the indexStates table >- indexLocation = (IPath) getIndexStates().getKey(getJavaPluginWorkingLocation().append(fileName)); >+ indexLocation = (IndexLocation) getIndexStates().getKey(new FileIndexLocation(new File(getSavedIndexesDirectory(), fileName))); > this.indexLocations.put(containerPath, indexLocation); > } > return indexLocation; >@@ -161,7 +164,7 @@ > > for (int i = 0, l = indexesFiles.length; i < l; i++) { > String fileName = indexesFiles[i].getAbsolutePath(); >- if (pathsToKeep != null && pathsToKeep.includes(fileName)) continue; >+ if (pathsToKeep != null && pathsToKeep.includes(new FileIndexLocation(indexesFiles[i]))) continue; > String suffix = ".index"; //$NON-NLS-1$ > if (fileName.regionMatches(true, fileName.length() - suffix.length(), suffix, 0, suffix.length())) { > if (VERBOSE || DEBUG) >@@ -173,7 +176,7 @@ > /* > * Creates an empty index at the given location, for the given container path, if none exist. > */ >-public synchronized void ensureIndexExists(IPath indexLocation, IPath containerPath) { >+public synchronized void ensureIndexExists(IndexLocation indexLocation, IPath containerPath) { > SimpleLookupTable states = getIndexStates(); > Object state = states.get(indexLocation); > if (state == null) { >@@ -207,7 +210,7 @@ > * @param indexLocation The path of the index file > * @return The corresponding index or <code>null</code> if not found > */ >-public synchronized Index getIndex(IPath indexLocation) { >+public synchronized Index getIndex(IndexLocation indexLocation) { > return (Index) this.indexes.get(indexLocation); // is null if unknown, call if the containerPath must be computed > } > /** >@@ -219,7 +222,7 @@ > * Warning: Does not check whether index is consistent (not being used) > */ > public synchronized Index getIndex(IPath containerPath, boolean reuseExistingFile, boolean createIfMissing) { >- IPath indexLocation = computeIndexLocation(containerPath); >+ IndexLocation indexLocation = computeIndexLocation(containerPath); > return getIndex(containerPath, indexLocation, reuseExistingFile, createIfMissing); > } > /** >@@ -230,7 +233,7 @@ > * > * Warning: Does not check whether index is consistent (not being used) > */ >-public synchronized Index getIndex(IPath containerPath, IPath indexLocation, boolean reuseExistingFile, boolean createIfMissing) { >+public synchronized Index getIndex(IPath containerPath, IndexLocation indexLocation, boolean reuseExistingFile, boolean createIfMissing) { > // Path is already canonical per construction > Index index = getIndex(indexLocation); > if (index == null) { >@@ -245,19 +248,17 @@ > > // index isn't cached, consider reusing an existing index file > String containerPathString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString(); >- String indexLocationString = indexLocation.toOSString(); > if (reuseExistingFile) { >- File indexFile = new File(indexLocationString); >- if (indexFile.exists()) { // check before creating index so as to avoid creating a new empty index if file is missing >+ if (indexLocation.exists()) { // check before creating index so as to avoid creating a new empty index if file is missing > try { >- index = new Index(indexLocationString, containerPathString, true /*reuse index file*/); >+ index = new Index(indexLocation, containerPathString, true /*reuse index file*/); > this.indexes.put(indexLocation, index); > return index; > } catch (IOException e) { > // failed to read the existing file or its no longer compatible >- if (currentIndexState != REBUILDING_STATE) { // rebuild index if existing file is corrupt, unless the index is already being rebuilt >+ if (currentIndexState != REBUILDING_STATE && currentIndexState != REUSE_STATE) { // rebuild index if existing file is corrupt, unless the index is already being rebuilt > if (VERBOSE) >- Util.verbose("-> cannot reuse existing index: "+indexLocationString+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$ >+ Util.verbose("-> cannot reuse existing index: "+indexLocation+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$ > rebuildIndex(indexLocation, containerPath); > return null; > } >@@ -268,18 +269,27 @@ > rebuildIndex(indexLocation, containerPath); > return null; > } >+ if (currentIndexState == REUSE_STATE) { >+ // supposed to be in reuse state but error in the index file, so reindex. >+ if (VERBOSE) >+ Util.verbose("-> cannot reuse given index: "+indexLocation+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$ >+ this.indexLocations.put(containerPath, null); >+ indexLocation = computeIndexLocation(containerPath); >+ rebuildIndex(indexLocation, containerPath); >+ return null; >+ } > } > // index wasn't found on disk, consider creating an empty new one > if (createIfMissing) { > try { > if (VERBOSE) >- Util.verbose("-> create empty index: "+indexLocationString+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$ >- index = new Index(indexLocationString, containerPathString, false /*do not reuse index file*/); >+ Util.verbose("-> create empty index: "+indexLocation+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$ >+ index = new Index(indexLocation, containerPathString, false /*do not reuse index file*/); > this.indexes.put(indexLocation, index); > return index; > } catch (IOException e) { > if (VERBOSE) >- Util.verbose("-> unable to create empty index: "+indexLocationString+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$ >+ Util.verbose("-> unable to create empty index: "+indexLocation+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$ > // The file could not be created. Possible reason: the project has been deleted. > return null; > } >@@ -295,7 +305,7 @@ > * @param locations The list of of the index files path > * @return The corresponding indexes list. > */ >-public Index[] getIndexes(IPath[] locations, IProgressMonitor progressMonitor) { >+public Index[] getIndexes(IndexLocation[] locations, IProgressMonitor progressMonitor) { > // acquire the in-memory indexes on the fly > int length = locations.length; > Index[] locatedIndexes = new Index[length]; >@@ -308,7 +318,7 @@ > throw new OperationCanceledException(); > } > // may trigger some index recreation work >- IPath indexLocation = locations[i]; >+ IndexLocation indexLocation = locations[i]; > Index index = getIndex(indexLocation); > if (index == null) { > // only need containerPath if the index must be built >@@ -330,18 +340,16 @@ > index = null; > } > } else { >- if (!getJavaPluginWorkingLocation().isPrefixOf(indexLocation)) { // the index belongs to non-jdt search participant >- if (indexLocation.toFile().exists()) { >- try { >- IPath container = getParticipantsContainer(indexLocation); >- if (container != null) { >- index = new Index(indexLocation.toOSString(), container.toOSString(), true /*reuse index file*/); >- this.indexes.put(indexLocation, index); >- } >- } catch (IOException e) { >- // ignore >+ if (indexLocation.isParticipantIndex() && indexLocation.exists()) { // the index belongs to non-jdt search participant >+ try { >+ IPath container = getParticipantsContainer(indexLocation); >+ if (container != null) { >+ index = new Index(indexLocation, container.toOSString(), true /*reuse index file*/); >+ this.indexes.put(indexLocation, index); > } >- } >+ } catch (IOException e) { >+ // ignore >+ } > } > } > } >@@ -358,7 +366,7 @@ > return locatedIndexes; > } > public synchronized Index getIndexForUpdate(IPath containerPath, boolean reuseExistingFile, boolean createIfMissing) { >- IPath indexLocation = computeIndexLocation(containerPath); >+ IndexLocation indexLocation = computeIndexLocation(containerPath); > if (getIndexStates().get(indexLocation) == REBUILDING_STATE) > return getIndex(containerPath, indexLocation, reuseExistingFile, createIfMissing); > >@@ -368,13 +376,13 @@ > if (this.indexStates != null) return this.indexStates; > > this.indexStates = new SimpleLookupTable(); >- IPath indexesDirectoryPath = getJavaPluginWorkingLocation(); >- char[][] savedNames = readIndexState(indexesDirectoryPath.toOSString()); >+ File indexesDirectoryPath = getSavedIndexesDirectory(); >+ char[][] savedNames = readIndexState(getJavaPluginWorkingLocation().toOSString()); > if (savedNames != null) { > for (int i = 1, l = savedNames.length; i < l; i++) { // first name is saved signature, see readIndexState() > char[] savedName = savedNames[i]; > if (savedName.length > 0) { >- IPath indexLocation = indexesDirectoryPath.append(new String(savedName)); // shares indexesDirectoryPath's segments >+ IndexLocation indexLocation = new FileIndexLocation(new File(indexesDirectoryPath, String.valueOf(savedName))); // shares indexesDirectoryPath's segments > if (VERBOSE) > Util.verbose("Reading saved index file " + indexLocation); //$NON-NLS-1$ > this.indexStates.put(indexLocation, SAVED_STATE); >@@ -387,9 +395,10 @@ > this.javaLikeNamesChanged = false; > deleteIndexFiles(); > } >+ readIndexMap(); > return this.indexStates; > } >-private IPath getParticipantsContainer(IPath indexLocation) { >+private IPath getParticipantsContainer(IndexLocation indexLocation) { > if (this.participantsContainers == null) { > readParticipantsIndexNamesFile(); > } >@@ -474,7 +483,7 @@ > for (int i = 0; i < entries.length; i++) { > IClasspathEntry entry= entries[i]; > if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) >- indexLibrary(entry.getPath(), project); >+ indexLibrary(entry.getPath(), project, ((ClasspathEntry)entry).getLibraryIndexLocation()); > } > } catch(JavaModelException e){ // cannot retrieve classpath info > } >@@ -488,16 +497,16 @@ > * Trigger addition of a library to an index > * Note: the actual operation is performed in background > */ >-public void indexLibrary(IPath path, IProject requestingProject) { >+public void indexLibrary(IPath path, IProject requestingProject, URL indexURL) { > // requestingProject is no longer used to cancel jobs but leave it here just in case >+ IndexLocation indexFile = indexURL != null ? IndexLocation.createIndexLocation(indexURL): null; > if (JavaCore.getPlugin() == null) return; >- >- Object target = JavaModel.getTarget(path, true); > IndexRequest request = null; >+ Object target = JavaModel.getTarget(path, true); > if (target instanceof IFile) { >- request = new AddJarFileToIndex((IFile) target, this); >+ request = new AddJarFileToIndex((IFile) target, indexFile, this); > } else if (target instanceof File) { >- request = new AddJarFileToIndex(path, this); >+ request = new AddJarFileToIndex(path, indexFile, this); > } else if (target instanceof IContainer) { > request = new IndexBinaryFolder((IContainer) target, this); > } else { >@@ -508,6 +517,20 @@ > if (!isJobWaiting(request)) > request(request); > } >+ >+synchronized boolean addIndex(IPath containerPath, IndexLocation indexFile) { >+ getIndexStates().put(indexFile, REUSE_STATE); >+ this.indexLocations.put(containerPath, indexFile); >+ Index index = getIndex(containerPath, indexFile, true, false); >+ if (index == null) { >+ indexFile.close(); >+ this.indexLocations.put(containerPath, null); >+ return false; >+ } >+ writeIndexMapFile(); >+ return true; >+} >+ > /** > * Index the content of the given source folder. > */ >@@ -522,7 +545,7 @@ > request(new AddFolderToIndex(sourceFolder, project, inclusionPatterns, exclusionPatterns, this)); > } > public synchronized void jobWasCancelled(IPath containerPath) { >- IPath indexLocation = computeIndexLocation(containerPath); >+ IndexLocation indexLocation = computeIndexLocation(containerPath); > Index index = getIndex(indexLocation); > if (index != null) { > index.monitor = null; >@@ -568,7 +591,7 @@ > } > return null; > } >-private void rebuildIndex(IPath indexLocation, IPath containerPath) { >+private void rebuildIndex(IndexLocation indexLocation, IPath containerPath) { > Object target = JavaModel.getTarget(containerPath, true); > if (target == null) return; > >@@ -584,9 +607,9 @@ > } else if (target instanceof IFolder) { > request = new IndexBinaryFolder((IFolder) target, this); > } else if (target instanceof IFile) { >- request = new AddJarFileToIndex((IFile) target, this); >+ request = new AddJarFileToIndex((IFile) target, null, this); > } else if (target instanceof File) { >- request = new AddJarFileToIndex(containerPath, this); >+ request = new AddJarFileToIndex(containerPath, null, this); > } > if (request != null) > request(request); >@@ -601,13 +624,13 @@ > String containerPathString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString(); > try { > // Path is already canonical >- IPath indexLocation = computeIndexLocation(containerPath); >+ IndexLocation indexLocation = computeIndexLocation(containerPath); > Index index = getIndex(indexLocation); > ReadWriteMonitor monitor = index == null ? null : index.monitor; > > if (VERBOSE) > Util.verbose("-> recreating index: "+indexLocation+" for path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$ >- index = new Index(indexLocation.toOSString(), containerPathString, false /*do not reuse index file*/); >+ index = new Index(indexLocation, containerPathString, false /*do not reuse index file*/); > this.indexes.put(indexLocation, index); > index.monitor = monitor; > return index; >@@ -634,7 +657,7 @@ > public synchronized void removeIndex(IPath containerPath) { > if (VERBOSE || DEBUG) > Util.verbose("removing index " + containerPath); //$NON-NLS-1$ >- IPath indexLocation = computeIndexLocation(containerPath); >+ IndexLocation indexLocation = computeIndexLocation(containerPath); > Index index = getIndex(indexLocation); > File indexFile = null; > if (index != null) { >@@ -642,8 +665,11 @@ > indexFile = index.getIndexFile(); > } > if (indexFile == null) >- indexFile = new File(indexLocation.toOSString()); // index is not cached yet, but still want to delete the file >- if (indexFile.exists()) { >+ indexFile = indexLocation.getIndexFile(); // index is not cached yet, but still want to delete the file >+ if (this.indexStates.get(indexLocation) == REUSE_STATE) { >+ indexLocation.close(); >+ this.indexLocations.put(containerPath, null); >+ } else if (indexFile != null && indexFile.exists()) { > if (DEBUG) > Util.verbose("removing index file " + indexFile); //$NON-NLS-1$ > indexFile.delete(); >@@ -659,24 +685,25 @@ > Util.verbose("removing index path " + path); //$NON-NLS-1$ > Object[] keyTable = this.indexes.keyTable; > Object[] valueTable = this.indexes.valueTable; >- IPath[] locations = null; >+ IndexLocation[] locations = null; > int max = this.indexes.elementSize; > int count = 0; > for (int i = 0, l = keyTable.length; i < l; i++) { >- IPath indexLocation = (IPath) keyTable[i]; >+ IndexLocation indexLocation = (IndexLocation) keyTable[i]; > if (indexLocation == null) > continue; >- if (path.isPrefixOf(indexLocation)) { >+ if (indexLocation.startsWith(path)) { > Index index = (Index) valueTable[i]; > index.monitor = null; > if (locations == null) >- locations = new IPath[max]; >+ locations = new IndexLocation[max]; > locations[count++] = indexLocation; >- File indexFile = index.getIndexFile(); >- if (indexFile.exists()) { >+ if (this.indexStates.get(indexLocation) == REUSE_STATE) { >+ indexLocation.close(); >+ } else { > if (DEBUG) >- Util.verbose("removing index file " + indexFile); //$NON-NLS-1$ >- indexFile.delete(); >+ Util.verbose("removing index file " + indexLocation); //$NON-NLS-1$ >+ indexLocation.delete(); > } > } else { > max--; >@@ -686,9 +713,15 @@ > for (int i = 0; i < count; i++) > this.indexes.removeKey(locations[i]); > removeIndexesState(locations); >- if (this.participantsContainers != null && this.participantsContainers.get(path.toOSString()) != null) { >- this.participantsContainers.removeKey(path.toOSString()); >- writeParticipantsIndexNamesFile(); >+ if (this.participantsContainers != null) { >+ boolean update = false; >+ for (int i = 0; i < count; i++) { >+ if (this.participantsContainers.get(locations[i]) != null) { >+ update = true; >+ this.participantsContainers.removeKey(locations[i]); >+ } >+ } >+ if (update) writeParticipantsIndexNamesFile(); > } > } > } >@@ -746,7 +779,7 @@ > String containerPathString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString(); > try { > // Path is already canonical >- IPath indexLocation = computeIndexLocation(containerPath); >+ IndexLocation indexLocation = computeIndexLocation(containerPath); > Index index = getIndex(indexLocation); > if (VERBOSE) { > Util.verbose("-> reseting index: "+indexLocation+" for path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$ >@@ -770,7 +803,7 @@ > // must have permission to write from the write monitor > if (index.hasChanged()) { > if (VERBOSE) >- Util.verbose("-> saving index " + index.getIndexFile()); //$NON-NLS-1$ >+ Util.verbose("-> saving index " + index.getIndexLocation()); //$NON-NLS-1$ > index.save(); > } > synchronized (this) { >@@ -782,7 +815,7 @@ > if (((IndexRequest) job).containerPath.equals(containerPath)) return; > } > } >- IPath indexLocation = computeIndexLocation(containerPath); >+ IndexLocation indexLocation = computeIndexLocation(containerPath); > updateIndexState(indexLocation, SAVED_STATE); > } > } >@@ -837,7 +870,7 @@ > } > this.needToSave = !allSaved; > } >-public void scheduleDocumentIndexing(final SearchDocument searchDocument, IPath container, final IPath indexLocation, final SearchParticipant searchParticipant) { >+public void scheduleDocumentIndexing(final SearchDocument searchDocument, IPath container, final IndexLocation indexLocation, final SearchParticipant searchParticipant) { > request(new IndexRequest(container, this) { > public boolean execute(IProgressMonitor progressMonitor) { > if (this.isCancelled || progressMonitor != null && progressMonitor.isCanceled()) return true; >@@ -850,7 +883,7 @@ > > try { > monitor.enterWrite(); // ask permission to write >- indexDocument(searchDocument, searchParticipant, index, indexLocation); >+ indexDocument(searchDocument, searchParticipant, index, new Path(indexLocation.getCanonicalFilePath())); > } finally { > monitor.exitWrite(); // free write lock > } >@@ -876,6 +909,27 @@ > return buffer.toString(); > } > >+private void readIndexMap() { >+ try { >+ char[] indexMaps = org.eclipse.jdt.internal.compiler.util.Util.getFileCharContent(this.indexNamesMapFile, null); >+ char[][] names = CharOperation.splitOn('\n', indexMaps); >+ if (names.length >= 3) { >+ // First line is DiskIndex signature (see writeIndexMapFile()) >+ String savedSignature = DiskIndex.SIGNATURE; >+ if (savedSignature.equals(new String(names[0]))) { >+ for (int i = 1, l = names.length-1 ; i < l ; i+=2) { >+ IndexLocation indexPath = IndexLocation.createIndexLocation(new URL(new String(names[i]))); >+ this.indexLocations.put(new Path(new String(names[i+1])), indexPath ); >+ this.indexStates.put(indexPath, REUSE_STATE); >+ } >+ } >+ } >+ } catch (IOException ignored) { >+ if (VERBOSE) >+ Util.verbose("Failed to read saved index file names"); //$NON-NLS-1$ >+ } >+ return; >+} > private char[][] readIndexState(String dirOSString) { > try { > char[] savedIndexNames = org.eclipse.jdt.internal.compiler.util.Util.getFileCharContent(this.savedIndexNamesFile, null); >@@ -904,7 +958,8 @@ > // First line is DiskIndex signature (see writeParticipantsIndexNamesFile()) > if (DiskIndex.SIGNATURE.equals(new String(names[0]))) { > for (int i = 1, l = names.length-1 ; i < l ; i+=2) { >- containers.put(new Path(new String(names[i])), new Path(new String(names[i+1]))); >+ IndexLocation indexLocation = new FileIndexLocation(new File(new String(names[i])), true); >+ containers.put(indexLocation, new Path(new String(names[i+1]))); > } > } > } >@@ -916,7 +971,7 @@ > this.participantsContainers = containers; > return; > } >-private synchronized void removeIndexesState(IPath[] locations) { >+private synchronized void removeIndexesState(IndexLocation[] locations) { > getIndexStates(); // ensure the states are initialized > int length = locations.length; > boolean changed = false; >@@ -932,9 +987,10 @@ > if (!changed) return; > > writeSavedIndexNamesFile(); >+ writeIndexMapFile(); > } >-private synchronized void updateIndexState(IPath indexLocation, Integer indexState) { >- if (indexLocation.isEmpty()) >+private synchronized void updateIndexState(IndexLocation indexLocation, Integer indexState) { >+ if (indexLocation == null) > throw new IllegalArgumentException(); > > getIndexStates(); // ensure the states are initialized >@@ -962,10 +1018,11 @@ > } > > } >-public void updateParticipant(IPath indexLocation, IPath containerPath) { >+public void updateParticipant(IPath indexPath, IPath containerPath) { > if (this.participantsContainers == null) { > readParticipantsIndexNamesFile(); >- } >+ } >+ IndexLocation indexLocation = new FileIndexLocation(indexPath.toFile(), true); > if (this.participantsContainers.get(indexLocation) == null) { > this.participantsContainers.put(indexLocation, containerPath); > this.participantUpdated = true; >@@ -1005,6 +1062,39 @@ > } > } > } >+private void writeIndexMapFile() { >+ BufferedWriter writer = null; >+ try { >+ writer = new BufferedWriter(new FileWriter(this.indexNamesMapFile)); >+ writer.write(DiskIndex.SIGNATURE); >+ writer.write('\n'); >+ Object[] keys = this.indexStates.keyTable; >+ Object[] states = this.indexStates.valueTable; >+ for (int i = 0, l = states.length; i < l; i++) { >+ IndexLocation location = (IndexLocation)keys[i]; >+ if (location != null && states[i] == REUSE_STATE) { >+ IPath container = (IPath)this.indexLocations.keyForValue(location); >+ if (container != null) { >+ writer.write(location.toString()); >+ writer.write('\n'); >+ writer.write(container.toOSString()); >+ writer.write('\n'); >+ } >+ } >+ } >+ } catch (IOException ignored) { >+ if (VERBOSE) >+ Util.verbose("Failed to write saved index file names", System.err); //$NON-NLS-1$ >+ } finally { >+ if (writer != null) { >+ try { >+ writer.close(); >+ } catch (IOException e) { >+ // ignore >+ } >+ } >+ } >+} > private void writeParticipantsIndexNamesFile() { > BufferedWriter writer = null; > try { >@@ -1014,9 +1104,9 @@ > Object[] indexFiles = this.participantsContainers.keyTable; > Object[] containers = this.participantsContainers.valueTable; > for (int i = 0, l = indexFiles.length; i < l; i++) { >- IPath indexFile = (IPath)indexFiles[i]; >+ IndexLocation indexFile = (IndexLocation)indexFiles[i]; > if (indexFile != null) { >- writer.write(indexFile.toOSString()); >+ writer.write(indexFile.getIndexFile().getPath()); > writer.write('\n'); > writer.write(((IPath)containers[i]).toOSString()); > writer.write('\n'); >@@ -1046,9 +1136,9 @@ > Object[] keys = this.indexStates.keyTable; > Object[] states = this.indexStates.valueTable; > for (int i = 0, l = states.length; i < l; i++) { >- IPath key = (IPath) keys[i]; >- if (key != null && !key.isEmpty() && states[i] == SAVED_STATE) { >- writer.write(key.lastSegment()); >+ IndexLocation key = (IndexLocation) keys[i]; >+ if (key != null && states[i] == SAVED_STATE) { >+ writer.write(key.fileName()); > writer.write('\n'); > } > } >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClassFileMatchLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClassFileMatchLocator.java >index 37608aa..1c86721 100644 >--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClassFileMatchLocator.java >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClassFileMatchLocator.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -90,6 +90,9 @@ > return true; > } > private boolean checkStandardAnnotations(long annotationTagBits, TypeReferencePattern pattern) { >+ if ((annotationTagBits & TagBits.AllStandardAnnotationsMask) == 0) { >+ return false; >+ } > if ((annotationTagBits & TagBits.AnnotationTargetMASK) != 0) { > char[][] compoundName = TypeConstants.JAVA_LANG_ANNOTATION_TARGET; > if (checkAnnotationTypeReference(CharOperation.concatWith(compoundName, '.'), pattern) || >@@ -142,18 +145,6 @@ > } > if ((annotationTagBits & TagBits.AnnotationPolymorphicSignature) != 0) { > char[][] compoundName = TypeConstants.JAVA_LANG_INVOKE_METHODHANDLE_$_POLYMORPHICSIGNATURE; >- if (checkAnnotationTypeReference(CharOperation.concatWith(compoundName, '.'), pattern)) { >- return true; >- } >- } >- if ((annotationTagBits & TagBits.AnnotationPostConstruct) != 0) { >- char[][] compoundName = TypeConstants.JAVAX_ANNOTATION_POSTCONSTRUCT; >- if (checkAnnotationTypeReference(CharOperation.concatWith(compoundName, '.'), pattern)) { >- return true; >- } >- } >- if ((annotationTagBits & TagBits.AnnotationPreDestroy) != 0) { >- char[][] compoundName = TypeConstants.JAVAX_ANNOTATION_PREDESTROY; > if (checkAnnotationTypeReference(CharOperation.concatWith(compoundName, '.'), pattern)) { > return true; > } >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java >index 93f987e..fb5de81 100644 >--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -70,9 +70,12 @@ > import org.eclipse.jdt.internal.core.SearchableEnvironment; > import org.eclipse.jdt.internal.core.SourceMapper; > import org.eclipse.jdt.internal.core.SourceMethod; >+import org.eclipse.jdt.internal.core.SourceType; > import org.eclipse.jdt.internal.core.SourceTypeElementInfo; > import org.eclipse.jdt.internal.core.index.Index; > import org.eclipse.jdt.internal.core.search.*; >+import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants; >+import org.eclipse.jdt.internal.core.util.ASTNodeFinder; > import org.eclipse.jdt.internal.core.util.HandleFactory; > import org.eclipse.jdt.internal.core.util.Util; > >@@ -145,6 +148,8 @@ > HashSet methodHandles; > > private final boolean searchPackageDeclaration; >+private int sourceStartOfMethodToRetain; >+private int sourceEndOfMethodToRetain; > > public static class WorkingCopyDocument extends JavaSearchDocument { > public org.eclipse.jdt.core.ICompilationUnit workingCopy; >@@ -293,6 +298,22 @@ > this.searchPackageDeclaration = ((OrPattern)pattern).hasPackageDeclaration(); > } else { > this.searchPackageDeclaration = false; >+ } >+ if (pattern instanceof MethodPattern) { >+ IType type = ((MethodPattern) pattern).declaringType; >+ if (type != null && !type.isBinary()) { >+ SourceType sourceType = (SourceType) type; >+ IMember local = sourceType.getOuterMostLocalContext(); >+ if (local instanceof IMethod) { // remember this method's range so we don't purge its statements. >+ try { >+ ISourceRange range = local.getSourceRange(); >+ this.sourceStartOfMethodToRetain = range.getOffset(); >+ this.sourceEndOfMethodToRetain = this.sourceStartOfMethodToRetain + range.getLength() - 1; // offset is 0 based. >+ } catch (JavaModelException e) { >+ // drop silently. >+ } >+ } >+ } > } > } > /** >@@ -876,10 +897,47 @@ > // Get binding from unit scope > char[][] compoundName = CharOperation.splitOn('.', typeName); > TypeBinding typeBinding = this.unitScope.getType(compoundName, compoundName.length); >+ if (typeBinding == null || !typeBinding.isValidBinding()) { >+ typeBinding = this.lookupEnvironment.getType(compoundName); >+ } > this.bindings.put(typeKey, typeBinding); >- return typeBinding.isValidBinding() ? typeBinding : null; >+ return typeBinding != null && typeBinding.isValidBinding() ? typeBinding : null; > } > public MethodBinding getMethodBinding(MethodPattern methodPattern) { >+ MethodBinding methodBinding = getMethodBinding0(methodPattern); >+ if (methodBinding != null) >+ return methodBinding; // known to be valid. >+ // special handling for methods of anonymous/local types. Since these cannot be looked up in the environment the usual way ... >+ if (methodPattern.focus instanceof SourceMethod) { >+ char[] typeName = PatternLocator.qualifiedPattern(methodPattern.declaringSimpleName, methodPattern.declaringQualification); >+ if (CharOperation.indexOf(IIndexConstants.ONE_STAR, typeName, true) >= 0) { // See org.eclipse.jdt.core.search.SearchPattern.enclosingTypeNames(IType) >+ IType type = methodPattern.declaringType; >+ IType enclosingType = type.getDeclaringType(); >+ while (enclosingType != null) { >+ type = enclosingType; >+ enclosingType = type.getDeclaringType(); >+ } >+ typeName = type.getFullyQualifiedName().toCharArray(); >+ TypeBinding declaringTypeBinding = getType(typeName, typeName); >+ if (declaringTypeBinding instanceof SourceTypeBinding) { >+ SourceTypeBinding sourceTypeBinding = ((SourceTypeBinding) declaringTypeBinding); >+ ClassScope skope = sourceTypeBinding.scope; >+ if (skope != null) { >+ CompilationUnitDeclaration unit = skope.referenceCompilationUnit(); >+ if (unit != null) { >+ AbstractMethodDeclaration amd = new ASTNodeFinder(unit).findMethod((IMethod) methodPattern.focus); >+ if (amd != null && amd.binding != null && amd.binding.isValidBinding()) { >+ this.bindings.put(methodPattern, amd.binding); >+ return amd.binding; >+ } >+ } >+ } >+ } >+ } >+ } >+ return null; >+} >+private MethodBinding getMethodBinding0(MethodPattern methodPattern) { > if (this.unitScope == null) return null; > // Try to get binding from cache > Binding binding = (Binding) this.bindings.get(methodPattern); >@@ -990,7 +1048,7 @@ > this.options, > new DefaultProblemFactory()); > this.lookupEnvironment = new LookupEnvironment(this, this.options, problemReporter, this.nameEnvironment); >- >+ this.lookupEnvironment.mayTolerateMissingType = true; > this.parser = MatchLocatorParser.createParser(problemReporter, this); > > // basic parser needs also to be reset as project options may have changed >@@ -1351,7 +1409,7 @@ > } > //*/ > protected IType lookupType(ReferenceBinding typeBinding) { >- if (typeBinding == null) return null; >+ if (typeBinding == null || !typeBinding.isValidBinding()) return null; > > char[] packageName = typeBinding.qualifiedPackageName(); > IPackageFragment[] pkgs = this.nameLookup.findPackageFragments( >@@ -1692,14 +1750,19 @@ > for (int j = 0, length = methods.length; j < length; j++) { > AbstractMethodDeclaration method = methods[j]; > if (!this.currentPossibleMatch.nodeSet.hasPossibleNodes(method.declarationSourceStart, method.declarationSourceEnd)) { >- method.statements = null; >- method.javadoc = null; >+ if (this.sourceStartOfMethodToRetain != method.declarationSourceStart || this.sourceEndOfMethodToRetain != method.declarationSourceEnd) { // approximate, but no big deal >+ method.statements = null; >+ method.javadoc = null; >+ } > } > } > } else { > for (int j = 0, length = methods.length; j < length; j++) { >- methods[j].statements = null; >- methods[j].javadoc = null; >+ AbstractMethodDeclaration method = methods[j]; >+ if (this.sourceStartOfMethodToRetain != method.declarationSourceStart || this.sourceEndOfMethodToRetain != method.declarationSourceEnd) { // approximate, but no big deal >+ method.statements = null; >+ method.javadoc = null; >+ } > } > } > } >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java >index 55e10cc..9b48938 100644 >--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -31,6 +31,7 @@ > //extra reference info > public char[][][] allSuperDeclaringTypeNames; > >+private MatchLocator matchLocator; > //method declarations which parameters verification fail > private HashMap methodDeclarationsWithInvalidParam = new HashMap(); > >@@ -82,6 +83,7 @@ > locator, > this.pattern.declaringType, > locator.progressMonitor).collect(); >+ this.matchLocator = locator; > } catch (JavaModelException e) { > // inaccurate matches will be found > } >@@ -251,7 +253,7 @@ > // return inaccurate match for ambiguous call (bug 80890) > return INACCURATE_MATCH; > } >- >+ boolean foundTypeVariable = false; > // verify each parameter > for (int i = 0; i < parameterCount; i++) { > TypeBinding argType = method.parameters[i]; >@@ -272,6 +274,9 @@ > // Do not consider match as impossible while finding declarations and source level >= 1.5 > // (see bugs https://bugs.eclipse.org/bugs/show_bug.cgi?id=79990, 96761, 96763) > newLevel = level; >+ } else if (argType.isTypeVariable()) { >+ newLevel = level; >+ foundTypeVariable = true; > } else { > return IMPOSSIBLE_MATCH; > } >@@ -279,10 +284,23 @@ > level = newLevel; // can only be downgraded > } > } >+ if (foundTypeVariable) { >+ if (!method.isStatic() && !method.isPrivate()) { >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=123836, No point in textually comparing type variables, captures etc with concrete types. >+ MethodBinding focusMethodBinding = this.matchLocator.getMethodBinding(this.pattern); >+ if (focusMethodBinding != null) { >+ if (matchOverriddenMethod(focusMethodBinding.declaringClass, focusMethodBinding, method)) { >+ return ACCURATE_MATCH; >+ } >+ } >+ } >+ return IMPOSSIBLE_MATCH; >+ } > } > > return level; > } >+// This works for only methods of parameterized types. > private boolean matchOverriddenMethod(ReferenceBinding type, MethodBinding method, MethodBinding matchMethod) { > if (type == null || this.pattern.selector == null) return false; > >diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PossibleMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PossibleMatch.java >index dc3450d..2a967c4 100644 >--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PossibleMatch.java >+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PossibleMatch.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation 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 >@@ -154,6 +154,9 @@ > hashCode += CharOperation.hashCode(this.compoundName[i]); > return hashCode; > } >+public boolean ignoreOptionalProblems() { >+ return false; >+} > void setSimilarMatch(PossibleMatch possibleMatch) { > // source does not matter on similar match as it is read on > // the first stored possible match
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 359724
:
211628
|
211642
|
211643