initial commit in accordance with CQ 3784
diff --git a/org.eclipse.jdt.core/.classpath b/org.eclipse.jdt.core/.classpath
new file mode 100644
index 0000000..c954139
--- /dev/null
+++ b/org.eclipse.jdt.core/.classpath
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" output="antbin" path="antadapter"/>
+ <classpathentry kind="src" path="util"/>
+ <classpathentry kind="src" path="batch"/>
+ <classpathentry kind="src" path="codeassist"/>
+ <classpathentry kind="src" path="compiler"/>
+ <classpathentry kind="src" path="dom"/>
+ <classpathentry kind="src" path="eval"/>
+ <classpathentry kind="src" path="formatter"/>
+ <classpathentry kind="src" path="model"/>
+ <classpathentry kind="src" path="search"/>
+ <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.core/.options b/org.eclipse.jdt.core/.options
new file mode 100644
index 0000000..07b4305
--- /dev/null
+++ b/org.eclipse.jdt.core/.options
@@ -0,0 +1,78 @@
+# Turn on debug tracing for org.eclipse.jdt.core plugin
+org.eclipse.jdt.core/debug=true
+
+# Reports buffer manager activity
+org.eclipse.jdt.core/debug/buffermanager=false
+
+# Reports incremental builder activity : nature of build, built state reading, indictment process
+org.eclipse.jdt.core/debug/builder=false
+
+# Reports compiler activity
+org.eclipse.jdt.core/debug/compiler=false
+
+# Reports codeassist completion activity : recovered unit, inferred completions
+org.eclipse.jdt.core/debug/completion=false
+
+# Reports classpath variable initialization, and classpath container resolution
+org.eclipse.jdt.core/debug/cpresolution=false
+
+# Reports internals of classpath variable initialization, and classpath container resolution (to be used on the JDT/Core team request only)
+org.eclipse.jdt.core/debug/cpresolution/advanced=false
+
+# Reports failures during classpath variable initialization, and classpath container resolution
+org.eclipse.jdt.core/debug/cpresolution/failure=false
+
+# Report type hierarchy connections, refreshes and deltas
+org.eclipse.jdt.core/debug/hierarchy=false
+
+# Reports background indexer activity: indexing, saving index file, index queries
+org.eclipse.jdt.core/debug/indexmanager=false
+
+# Print notified Java element deltas
+org.eclipse.jdt.core/debug/javadelta=false
+org.eclipse.jdt.core/debug/javadelta/verbose=false
+
+# Reports various Java model activities
+org.eclipse.jdt.core/debug/javamodel=false
+
+# Reports Java model elements opening/closing
+org.eclipse.jdt.core/debug/javamodel/cache=false
+
+# Reports post actions addition/run
+org.eclipse.jdt.core/debug/postaction=false
+
+# Reports name resolution activity
+org.eclipse.jdt.core/debug/resolution=false
+
+# Reports java search activity
+org.eclipse.jdt.core/debug/search=false
+
+# Reports source mapper activity
+org.eclipse.jdt.core/debug/sourcemapper=false
+
+# Reports code formatter activity
+org.eclipse.jdt.core/debug/formatter=false
+
+# Reports open on selection activity : recovered unit, inferred selection
+org.eclipse.jdt.core/debug/selection=false
+
+# Reports access to zip and jar files through the Java model
+org.eclipse.jdt.core/debug/zipaccess=false
+
+# Reports the time to perform code completion.
+org.eclipse.jdt.core/perf/completion=300
+
+# Reports the time to perform code selection.
+org.eclipse.jdt.core/perf/selection=300
+
+# Reports the time to process a java element delta.
+org.eclipse.jdt.core/perf/javadeltalistener=500
+
+# Reports the time to perform an initialization of a classpath variable.
+org.eclipse.jdt.core/perf/variableinitializer=5000
+
+# Reports the time to perform an initialization of a classpath container.
+org.eclipse.jdt.core/perf/containerinitializer=5000
+
+# Reports the time to perform a reconcile operation.
+org.eclipse.jdt.core/perf/reconcile=1000
diff --git a/org.eclipse.jdt.core/.project b/org.eclipse.jdt.core/.project
new file mode 100644
index 0000000..63121f2
--- /dev/null
+++ b/org.eclipse.jdt.core/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.jdt.core</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.core/.settings/.api_filters b/org.eclipse.jdt.core/.settings/.api_filters
new file mode 100644
index 0000000..fc466c9
--- /dev/null
+++ b/org.eclipse.jdt.core/.settings/.api_filters
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<component id="org.eclipse.jdt.core" version="2">
+ <resource path="dom/org/eclipse/jdt/core/dom/ASTParser.java" type="org.eclipse.jdt.core.dom.ASTParser">
+ <filter id="1142947843">
+ <message_arguments>
+ <message_argument value="3.5.2"/>
+ <message_argument value="setIgnoreMethodBodies(boolean)"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="model/org/eclipse/jdt/core/ICompilationUnit.java" type="org.eclipse.jdt.core.ICompilationUnit">
+ <filter id="1210056707">
+ <message_arguments>
+ <message_argument value="3.5.2"/>
+ <message_argument value="IGNORE_METHOD_BODIES"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="search/org/eclipse/jdt/core/search/TypeNameMatch.java" type="org.eclipse.jdt.core.search.TypeNameMatch">
+ <filter id="336744520">
+ <message_arguments>
+ <message_argument value="org.eclipse.jdt.core.search.TypeNameMatch"/>
+ </message_arguments>
+ </filter>
+ </resource>
+</component>
diff --git a/org.eclipse.jdt.core/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jdt.core/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..a2db53e
--- /dev/null
+++ b/org.eclipse.jdt.core/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,354 @@
+#Wed Oct 28 15:47:39 CET 2009
+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.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=ignore
+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.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.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+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=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=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.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+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.uncheckedTypeOperation=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.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.core/.settings/org.eclipse.jdt.ui.prefs b/org.eclipse.jdt.core/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..b83ebb4
--- /dev/null
+++ b/org.eclipse.jdt.core/.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=false
+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.core/.settings/org.eclipse.pde.api.tools.prefs b/org.eclipse.jdt.core/.settings/org.eclipse.pde.api.tools.prefs
new file mode 100644
index 0000000..c9c5910
--- /dev/null
+++ b/org.eclipse.jdt.core/.settings/org.eclipse.pde.api.tools.prefs
@@ -0,0 +1,88 @@
+#Mon Nov 24 17:11:53 CET 2008
+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_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
+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
diff --git a/org.eclipse.jdt.core/.settings/org.eclipse.pde.prefs b/org.eclipse.jdt.core/.settings/org.eclipse.pde.prefs
new file mode 100644
index 0000000..e7df45d
--- /dev/null
+++ b/org.eclipse.jdt.core/.settings/org.eclipse.pde.prefs
@@ -0,0 +1,16 @@
+#Thu Nov 01 22:46:18 EDT 2007
+compilers.incompatible-environment=1
+compilers.p.build=1
+compilers.p.deprecated=1
+compilers.p.missing-bundle-classpath-entries=2
+compilers.p.missing-packages=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-resource=1
+compilers.p.unresolved-ex-points=0
+compilers.p.unresolved-import=0
+compilers.use-project=true
+eclipse.preferences.version=1
diff --git a/org.eclipse.jdt.core/META-INF/Bootstrap_MANIFEST.MF b/org.eclipse.jdt.core/META-INF/Bootstrap_MANIFEST.MF
new file mode 100644
index 0000000..dcab0e5
--- /dev/null
+++ b/org.eclipse.jdt.core/META-INF/Bootstrap_MANIFEST.MF
@@ -0,0 +1,80 @@
+Manifest-Version: 1.0
+Main-Class: org.eclipse.jdt.internal.compiler.batch.Main
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.jdt.core; singleton:=true
+Bundle-Version: 3.6.0.v_A32a
+Bundle-Activator: org.eclipse.jdt.core.JavaCore
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Export-Package: org.eclipse.jdt.core,
+ org.eclipse.jdt.core.compiler,
+ org.eclipse.jdt.core.compiler.batch,
+ org.eclipse.jdt.core.dom,
+ org.eclipse.jdt.core.dom.rewrite,
+ org.eclipse.jdt.core.eval,
+ org.eclipse.jdt.core.formatter,
+ org.eclipse.jdt.core.jdom,
+ org.eclipse.jdt.core.search,
+ org.eclipse.jdt.core.util,
+ 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,
+ org.eclipse.jdt.internal.codeassist.select;x-internal:=true,
+ org.eclipse.jdt.internal.compiler;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.ast;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.batch;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.classfmt;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.codegen;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.env;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.flow;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.impl;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.lookup;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.parser;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.parser.diagnose;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.problem;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.util;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.core;x-friends:="org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.core.builder;x-friends:="org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.core.dom;x-internal:=true,
+ org.eclipse.jdt.internal.core.dom.rewrite;x-internal:=true,
+ org.eclipse.jdt.internal.core.eval;x-internal:=true,
+ org.eclipse.jdt.internal.core.hierarchy;x-internal:=true,
+ org.eclipse.jdt.internal.core.index;x-internal:=true,
+ org.eclipse.jdt.internal.core.jdom;x-internal:=true,
+ org.eclipse.jdt.internal.core.search;x-internal:=true,
+ org.eclipse.jdt.internal.core.search.indexing;x-internal:=true,
+ org.eclipse.jdt.internal.core.search.matching;x-internal:=true,
+ org.eclipse.jdt.internal.core.search.processing;x-internal:=true,
+ org.eclipse.jdt.internal.core.util;x-friends:="org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.eval;x-internal:=true,
+ org.eclipse.jdt.internal.formatter;x-internal:=true,
+ org.eclipse.jdt.internal.formatter.align;x-internal:=true,
+ org.eclipse.jdt.internal.formatter.comment;x-internal:=true,
+ org.eclipse.jdt.internal.formatter.old;x-internal:=true,
+ org.eclipse.objectteams.otdt.core,
+ org.eclipse.objectteams.otdt.core.compiler,
+ org.eclipse.objectteams.otdt.core.exceptions,
+ org.eclipse.objectteams.otdt.core.search,
+ org.eclipse.objectteams.otdt.core.util,
+ org.eclipse.objectteams.otdt.core.internal.compiler.bytecode,
+ org.eclipse.objectteams.otdt.core.internal.compiler.control,
+ org.eclipse.objectteams.otdt.core.internal.compiler.lifting,
+ org.eclipse.objectteams.otdt.core.internal.compiler.mappings,
+ org.eclipse.objectteams.otdt.core.internal.compiler.model,
+ org.eclipse.objectteams.otdt.core.internal.compiler.problem,
+ org.eclipse.objectteams.otdt.core.internal.compiler.smap,
+ org.eclipse.objectteams.otdt.core.internal.compiler.statemachine.copyinheritance,
+ org.eclipse.objectteams.otdt.core.internal.compiler.statemachine.transformer,
+ org.eclipse.objectteams.otdt.core.internal.compiler.util,
+ org.eclipse.objectteams.otdt.internal.codeassist,
+ org.eclipse.objectteams.otdt.internal.core;x-internal:=true,
+ org.eclipse.objectteams.otdt.internal.core.builder;x-friends:="org.eclipse.objectteams.otdt"
+Require-Bundle: org.eclipse.core.resources;bundle-version="[3.3.0,4.0.0)",
+ org.eclipse.core.runtime;bundle-version="[3.3.0,4.0.0)",
+ org.eclipse.core.filesystem;bundle-version="[1.0.0,2.0.0)",
+ org.eclipse.text;bundle-version="[3.1.0,4.0.0)",
+ org.eclipse.team.core;bundle-version="[3.1.0,4.0.0)";resolution:=optional
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Eclipse-ExtensibleAPI: true
+Bundle-ActivationPolicy: lazy
diff --git a/org.eclipse.jdt.core/META-INF/MANIFEST.MF b/org.eclipse.jdt.core/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..23b042c
--- /dev/null
+++ b/org.eclipse.jdt.core/META-INF/MANIFEST.MF
@@ -0,0 +1,82 @@
+Manifest-Version: 1.0
+Main-Class: org.eclipse.jdt.internal.compiler.batch.Main
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.jdt.core; singleton:=true
+Bundle-Version: 3.6.0.v_OTDT_r140_qualifier
+Bundle-Activator: org.eclipse.jdt.core.JavaCore
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Export-Package: org.eclipse.jdt.core,
+ org.eclipse.jdt.core.compiler,
+ org.eclipse.jdt.core.compiler.batch,
+ org.eclipse.jdt.core.dom,
+ org.eclipse.jdt.core.dom.rewrite,
+ org.eclipse.jdt.core.eval,
+ org.eclipse.jdt.core.formatter,
+ org.eclipse.jdt.core.jdom,
+ org.eclipse.jdt.core.search,
+ org.eclipse.jdt.core.util,
+ 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,
+ org.eclipse.jdt.internal.codeassist.select;x-internal:=true,
+ org.eclipse.jdt.internal.compiler;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.ast;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.batch;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.classfmt;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.codegen;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.env;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.flow;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.impl;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.lookup;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.parser;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.parser.diagnose;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.problem;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.util;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.core;x-friends:="org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.core.builder;x-friends:="org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.core.dom;x-internal:=true,
+ org.eclipse.jdt.internal.core.dom.rewrite;x-internal:=true,
+ org.eclipse.jdt.internal.core.eval;x-internal:=true,
+ org.eclipse.jdt.internal.core.hierarchy;x-internal:=true,
+ org.eclipse.jdt.internal.core.index;x-internal:=true,
+ org.eclipse.jdt.internal.core.jdom;x-internal:=true,
+ org.eclipse.jdt.internal.core.search;x-internal:=true,
+ org.eclipse.jdt.internal.core.search.indexing;x-internal:=true,
+ org.eclipse.jdt.internal.core.search.matching;x-internal:=true,
+ org.eclipse.jdt.internal.core.search.processing;x-internal:=true,
+ org.eclipse.jdt.internal.core.util;x-friends:="org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.eval;x-internal:=true,
+ org.eclipse.jdt.internal.formatter;x-internal:=true,
+ org.eclipse.jdt.internal.formatter.align;x-internal:=true,
+ org.eclipse.jdt.internal.formatter.comment;x-internal:=true,
+ org.eclipse.jdt.internal.formatter.old;x-internal:=true,
+ org.eclipse.objectteams.otdt.core,
+ org.eclipse.objectteams.otdt.core.compiler,
+ org.eclipse.objectteams.otdt.core.exceptions,
+ org.eclipse.objectteams.otdt.core.search,
+ org.eclipse.objectteams.otdt.core.util,
+ org.eclipse.objectteams.otdt.internal.codeassist,
+ org.eclipse.objectteams.otdt.internal.core;x-friends:="org.eclipse.objectteams.otdt.ui.tests.refactoring",
+ org.eclipse.objectteams.otdt.internal.core.builder;x-friends:="org.eclipse.objectteams.otdt",
+ org.eclipse.objectteams.otdt.internal.core.compiler.ast;x-friends:="org.eclipse.jdt.core.tests.compiler",
+ org.eclipse.objectteams.otdt.internal.core.compiler.bytecode;x-friends:="org.eclipse.objectteams.otdt.compiler.adaptor",
+ org.eclipse.objectteams.otdt.internal.core.compiler.control;x-friends:="org.eclipse.objectteams.otdt.tests,org.eclipse.objectteams.otdt.apt",
+ org.eclipse.objectteams.otdt.internal.core.compiler.lifting;x-friends:="org.eclipse.objectteams.otdt.compiler.adaptor",
+ org.eclipse.objectteams.otdt.internal.core.compiler.lookup;x-friends:="org.eclipse.objectteams.otdt.compiler.adaptor",
+ org.eclipse.objectteams.otdt.internal.core.compiler.mappings;x-internal:=true,
+ org.eclipse.objectteams.otdt.internal.core.compiler.model;x-friends:="org.eclipse.objectteams.otdt.apt",
+ org.eclipse.objectteams.otdt.internal.core.compiler.problem;x-internal:=true,
+ org.eclipse.objectteams.otdt.internal.core.compiler.smap;x-friends:="org.eclipse.objectteams.otdt.tests",
+ org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.copyinheritance;x-friends:="org.eclipse.objectteams.otdt.compiler.adaptor",
+ org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.transformer;x-internal:=true,
+ org.eclipse.objectteams.otdt.internal.core.compiler.util;x-internal:=true
+Require-Bundle: org.eclipse.core.resources;bundle-version="[3.3.0,4.0.0)",
+ org.eclipse.core.runtime;bundle-version="[3.3.0,4.0.0)",
+ org.eclipse.core.filesystem;bundle-version="[1.0.0,2.0.0)",
+ org.eclipse.text;bundle-version="[3.1.0,4.0.0)",
+ org.eclipse.team.core;bundle-version="[3.1.0,4.0.0)";resolution:=optional
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Eclipse-ExtensibleAPI: true
+Bundle-ActivationPolicy: lazy
diff --git a/org.eclipse.jdt.core/META-INF/eclipse.inf b/org.eclipse.jdt.core/META-INF/eclipse.inf
new file mode 100644
index 0000000..32d8ee1
--- /dev/null
+++ b/org.eclipse.jdt.core/META-INF/eclipse.inf
@@ -0,0 +1 @@
+jarprocessor.exclude.children=true
diff --git a/org.eclipse.jdt.core/about.html b/org.eclipse.jdt.core/about.html
new file mode 100644
index 0000000..74d0269
--- /dev/null
+++ b/org.eclipse.jdt.core/about.html
@@ -0,0 +1,36 @@
+<!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>May 11, 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>
+
+<h3>Disassembler</h3>
+<p>This plug-in contains a bytecode disassembler ("Disassembler") that can produce a listing of the Java assembler mnemonics ("Assembler Mnemonics") for a Java method. If you
+use the Disassembler to view the Assembler Mnemonics for a method, you should ensure that doing so will not violate the terms of any licenses that apply to your use of that method, as
+such licenses may not permit you to reverse engineer, decompile, or disassemble method bytecodes.</p>
+
+<h4>Version</h4>
+This version of the JDT has been modified for the Object Teams Development Tooling (v1.4.0M2, Fri Dec 11, 2009)
+
+</body>
+</html>
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/antadapter/META-INF/eclipse.inf b/org.eclipse.jdt.core/antadapter/META-INF/eclipse.inf
new file mode 100644
index 0000000..54e4b72
--- /dev/null
+++ b/org.eclipse.jdt.core/antadapter/META-INF/eclipse.inf
@@ -0,0 +1,2 @@
+jarprocessor.exclude.sign=true
+jarprocessor.exclude.children=true
diff --git a/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/CheckDebugAttributes.java b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/CheckDebugAttributes.java
new file mode 100644
index 0000000..f498c04
--- /dev/null
+++ b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/CheckDebugAttributes.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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 java.util.Enumeration;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipException;
+import java.util.zip.ZipFile;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.eclipse.jdt.core.util.IClassFileReader;
+import org.eclipse.jdt.core.util.ICodeAttribute;
+import org.eclipse.jdt.core.util.IMethodInfo;
+import org.eclipse.jdt.internal.antadapter.AntAdapterMessages;
+
+/**
+ * <p>An Ant task to find out if a class file or a jar contains debug attributes. If this is the case,
+ * the property contains the value "has debug" after the call.
+ * </p>
+ * <p>
+ * <code><eclipse.checkDebugAttributes property="hasDebug" file="${basedir}/bin/p/A.class"/></code>
+ * </p>
+ * <p>
+ * For more information on Ant check out the website at http://jakarta.apache.org/ant/ .
+ * </p>
+ *
+ * This is not intended to be subclassed by users.
+ * @since 2.0
+ */
+public final class CheckDebugAttributes extends Task {
+
+ private String file;
+ private String property;
+
+ public void execute() throws BuildException {
+ if (this.file == null) {
+ throw new BuildException(AntAdapterMessages.getString("checkDebugAttributes.file.argument.cannot.be.null")); //$NON-NLS-1$
+ }
+ if (this.property == null) {
+ throw new BuildException(AntAdapterMessages.getString("checkDebugAttributes.property.argument.cannot.be.null")); //$NON-NLS-1$
+ }
+ try {
+ boolean hasDebugAttributes = false;
+ if (org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(this.file)) {
+ IClassFileReader classFileReader = ToolFactory.createDefaultClassFileReader(this.file, IClassFileReader.ALL);
+ hasDebugAttributes = checkClassFile(classFileReader);
+ } else {
+ ZipFile jarFile = null;
+ try {
+ jarFile = new ZipFile(this.file);
+ } catch (ZipException e) {
+ throw new BuildException(AntAdapterMessages.getString("checkDebugAttributes.file.argument.must.be.a.classfile.or.a.jarfile")); //$NON-NLS-1$
+ }
+ for (Enumeration entries = jarFile.entries(); !hasDebugAttributes && entries.hasMoreElements(); ) {
+ ZipEntry entry = (ZipEntry) entries.nextElement();
+ if (org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(entry.getName())) {
+ IClassFileReader classFileReader = ToolFactory.createDefaultClassFileReader(this.file, entry.getName(), IClassFileReader.ALL);
+ hasDebugAttributes = checkClassFile(classFileReader);
+ }
+ }
+ }
+ if (hasDebugAttributes) {
+ getProject().setUserProperty(this.property, "has debug"); //$NON-NLS-1$
+ }
+ } catch (IOException e) {
+ throw new BuildException(AntAdapterMessages.getString("checkDebugAttributes.ioexception.occured") + this.file); //$NON-NLS-1$
+ }
+ }
+
+ private boolean checkClassFile(IClassFileReader classFileReader) {
+ IMethodInfo[] methodInfos = classFileReader.getMethodInfos();
+ for (int i = 0, max = methodInfos.length; i < max; i++) {
+ ICodeAttribute codeAttribute = methodInfos[i].getCodeAttribute();
+ if (codeAttribute != null && codeAttribute.getLineNumberAttribute() != null) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void setFile(String value) {
+ this.file = value;
+ }
+
+ public void setProperty(String value) {
+ this.property = value;
+ }
+}
diff --git a/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/JDTCompilerAdapter.java b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/JDTCompilerAdapter.java
new file mode 100644
index 0000000..475b9fe
--- /dev/null
+++ b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/JDTCompilerAdapter.java
@@ -0,0 +1,575 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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
+ * 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.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Javac;
+import org.apache.tools.ant.taskdefs.compilers.DefaultCompilerAdapter;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Commandline.Argument;
+import org.apache.tools.ant.util.JavaEnvUtils;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.antadapter.AntAdapterMessages;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+/**
+ * Ant 1.5 compiler adapter for the Eclipse Java compiler. This adapter permits the
+ * Eclipse Java compiler to be used with the <code>javac</code> task in Ant scripts. In order
+ * to use it, just set the property <code>build.compiler</code> as follows:
+ * <p>
+ * <code><property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/></code>
+ * </p>
+ * <p>
+ * For more information on Ant check out the website at http://jakarta.apache.org/ant/ .
+ * </p>
+ *
+ * @since 2.0
+ */
+public class JDTCompilerAdapter extends DefaultCompilerAdapter {
+ private static final char[] SEPARATOR_CHARS = new char[] { '/', '\\' };
+ private static final char[] ADAPTER_PREFIX = "#ADAPTER#".toCharArray(); //$NON-NLS-1$
+ private static final char[] ADAPTER_ENCODING = "ENCODING#".toCharArray(); //$NON-NLS-1$
+ private static final char[] ADAPTER_ACCESS = "ACCESS#".toCharArray(); //$NON-NLS-1$
+ private static String compilerClass = "org.eclipse.jdt.internal.compiler.batch.Main"; //$NON-NLS-1$
+ String logFileName;
+ Map customDefaultOptions;
+ private Map fileEncodings = null;
+ private Map dirEncodings = null;
+ private List accessRules = null;
+
+ /**
+ * Performs a compile using the JDT batch compiler
+ * @throws BuildException if anything wrong happen during the compilation
+ * @return boolean true if the compilation is ok, false otherwise
+ */
+ public boolean execute() throws BuildException {
+ this.attributes.log(AntAdapterMessages.getString("ant.jdtadapter.info.usingJDTCompiler"), Project.MSG_VERBOSE); //$NON-NLS-1$
+ Commandline cmd = setupJavacCommand();
+
+ try {
+ Class c = Class.forName(compilerClass);
+ Constructor batchCompilerConstructor = c.getConstructor(new Class[] { PrintWriter.class, PrintWriter.class, Boolean.TYPE, Map.class});
+ Object batchCompilerInstance = batchCompilerConstructor.newInstance(new Object[] {new PrintWriter(System.out), new PrintWriter(System.err), Boolean.TRUE, this.customDefaultOptions});
+ Method compile = c.getMethod("compile", new Class[] {String[].class}); //$NON-NLS-1$
+ Object result = compile.invoke(batchCompilerInstance, new Object[] { cmd.getArguments()});
+ final boolean resultValue = ((Boolean) result).booleanValue();
+ if (!resultValue && this.logFileName != null) {
+ this.attributes.log(AntAdapterMessages.getString("ant.jdtadapter.error.compilationFailed", this.logFileName)); //$NON-NLS-1$
+ }
+ return resultValue;
+ } catch (ClassNotFoundException cnfe) {
+ throw new BuildException(AntAdapterMessages.getString("ant.jdtadapter.error.cannotFindJDTCompiler")); //$NON-NLS-1$
+ } catch (Exception ex) {
+ throw new BuildException(ex);
+ }
+ }
+
+
+ protected Commandline setupJavacCommand() throws BuildException {
+ Commandline cmd = new Commandline();
+ this.customDefaultOptions = new CompilerOptions().getMap();
+
+ Class javacClass = Javac.class;
+
+ /*
+ * Read in the compiler arguments first since we might need to modify
+ * the classpath if any access rules were specified
+ */
+ String [] compilerArgs = processCompilerArguments(javacClass);
+
+ /*
+ * This option is used to never exit at the end of the ant task.
+ */
+ cmd.createArgument().setValue("-noExit"); //$NON-NLS-1$
+
+ if (this.bootclasspath != null) {
+ cmd.createArgument().setValue("-bootclasspath"); //$NON-NLS-1$
+ if (this.bootclasspath.size() != 0) {
+ /*
+ * Set the bootclasspath for the Eclipse compiler.
+ */
+ cmd.createArgument().setPath(this.bootclasspath);
+ } else {
+ cmd.createArgument().setValue(Util.EMPTY_STRING);
+ }
+ }
+
+ Path classpath = new Path(this.project);
+
+ /*
+ * Eclipse compiler doesn't support -extdirs.
+ * It is emulated using the classpath. We add extdirs entries after the
+ * bootclasspath.
+ */
+ if (this.extdirs != null) {
+ cmd.createArgument().setValue("-extdirs"); //$NON-NLS-1$
+ cmd.createArgument().setPath(this.extdirs);
+ }
+
+ /*
+ * The java runtime is already handled, so we simply want to retrieve the
+ * ant runtime and the compile classpath.
+ */
+ classpath.append(getCompileClasspath());
+
+ // For -sourcepath, use the "sourcepath" value if present.
+ // Otherwise default to the "srcdir" value.
+ Path sourcepath = null;
+
+ // retrieve the method getSourcepath() using reflect
+ // This is done to improve the compatibility to ant 1.5
+ Method getSourcepathMethod = null;
+ try {
+ getSourcepathMethod = javacClass.getMethod("getSourcepath", null); //$NON-NLS-1$
+ } catch(NoSuchMethodException e) {
+ // if not found, then we cannot use this method (ant 1.5)
+ }
+ Path compileSourcePath = null;
+ if (getSourcepathMethod != null) {
+ try {
+ compileSourcePath = (Path) getSourcepathMethod.invoke(this.attributes, null);
+ } catch (IllegalAccessException e) {
+ // should never happen
+ } catch (InvocationTargetException e) {
+ // should never happen
+ }
+ }
+ if (compileSourcePath != null) {
+ sourcepath = compileSourcePath;
+ } else {
+ sourcepath = this.src;
+ }
+ classpath.append(sourcepath);
+ /*
+ * Set the classpath for the Eclipse compiler.
+ */
+ cmd.createArgument().setValue("-classpath"); //$NON-NLS-1$
+ createClasspathArgument(cmd, classpath);
+
+ final String javaVersion = JavaEnvUtils.getJavaVersion();
+ String memoryParameterPrefix = javaVersion.equals(JavaEnvUtils.JAVA_1_1) ? "-J-" : "-J-X";//$NON-NLS-1$//$NON-NLS-2$
+ if (this.memoryInitialSize != null) {
+ if (!this.attributes.isForkedJavac()) {
+ this.attributes.log(AntAdapterMessages.getString("ant.jdtadapter.info.ignoringMemoryInitialSize"), Project.MSG_WARN); //$NON-NLS-1$
+ } else {
+ cmd.createArgument().setValue(memoryParameterPrefix
+ + "ms" + this.memoryInitialSize); //$NON-NLS-1$
+ }
+ }
+
+ if (this.memoryMaximumSize != null) {
+ if (!this.attributes.isForkedJavac()) {
+ this.attributes.log(AntAdapterMessages.getString("ant.jdtadapter.info.ignoringMemoryMaximumSize"), Project.MSG_WARN); //$NON-NLS-1$
+ } else {
+ cmd.createArgument().setValue(memoryParameterPrefix
+ + "mx" + this.memoryMaximumSize); //$NON-NLS-1$
+ }
+ }
+
+ if (this.debug) {
+ // retrieve the method getSourcepath() using reflect
+ // This is done to improve the compatibility to ant 1.5
+ Method getDebugLevelMethod = null;
+ try {
+ getDebugLevelMethod = javacClass.getMethod("getDebugLevel", null); //$NON-NLS-1$
+ } catch(NoSuchMethodException e) {
+ // if not found, then we cannot use this method (ant 1.5)
+ // debug level is only available with ant 1.5.x
+ }
+ String debugLevel = null;
+ if (getDebugLevelMethod != null) {
+ try {
+ debugLevel = (String) getDebugLevelMethod.invoke(this.attributes, null);
+ } catch (IllegalAccessException e) {
+ // should never happen
+ } catch (InvocationTargetException e) {
+ // should never happen
+ }
+ }
+ if (debugLevel != null) {
+ this.customDefaultOptions.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.DO_NOT_GENERATE);
+ this.customDefaultOptions.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.DO_NOT_GENERATE);
+ this.customDefaultOptions.put(CompilerOptions.OPTION_SourceFileAttribute , CompilerOptions.DO_NOT_GENERATE);
+ if (debugLevel.length() != 0) {
+ if (debugLevel.indexOf("vars") != -1) {//$NON-NLS-1$
+ this.customDefaultOptions.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.GENERATE);
+ }
+ if (debugLevel.indexOf("lines") != -1) {//$NON-NLS-1$
+ this.customDefaultOptions.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.GENERATE);
+ }
+ if (debugLevel.indexOf("source") != -1) {//$NON-NLS-1$
+ this.customDefaultOptions.put(CompilerOptions.OPTION_SourceFileAttribute , CompilerOptions.GENERATE);
+ }
+ }
+ } else {
+ this.customDefaultOptions.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.GENERATE);
+ this.customDefaultOptions.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.GENERATE);
+ this.customDefaultOptions.put(CompilerOptions.OPTION_SourceFileAttribute , CompilerOptions.GENERATE);
+ }
+ } else {
+ this.customDefaultOptions.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.DO_NOT_GENERATE);
+ this.customDefaultOptions.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.DO_NOT_GENERATE);
+ this.customDefaultOptions.put(CompilerOptions.OPTION_SourceFileAttribute , CompilerOptions.DO_NOT_GENERATE);
+ }
+
+ /*
+ * Handle the nowarn option. If none, then we generate all warnings.
+ */
+ if (this.attributes.getNowarn()) {
+ // disable all warnings
+ Object[] entries = this.customDefaultOptions.entrySet().toArray();
+ for (int i = 0, max = entries.length; i < max; i++) {
+ Map.Entry entry = (Map.Entry) entries[i];
+ if (!(entry.getKey() instanceof String))
+ continue;
+ if (!(entry.getValue() instanceof String))
+ continue;
+ if (((String) entry.getValue()).equals(CompilerOptions.WARNING)) {
+ this.customDefaultOptions.put(entry.getKey(), CompilerOptions.IGNORE);
+ }
+ }
+ this.customDefaultOptions.put(CompilerOptions.OPTION_TaskTags, Util.EMPTY_STRING);
+ if (this.deprecation) {
+ this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.WARNING);
+ this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode, CompilerOptions.ENABLED);
+ this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod, CompilerOptions.ENABLED);
+ }
+ } else if (this.deprecation) {
+ this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.WARNING);
+ this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode, CompilerOptions.ENABLED);
+ this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod, CompilerOptions.ENABLED);
+ } else {
+ this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.IGNORE);
+ this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode, CompilerOptions.DISABLED);
+ this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod, CompilerOptions.DISABLED);
+ }
+
+ /*
+ * destDir option.
+ */
+ if (this.destDir != null) {
+ cmd.createArgument().setValue("-d"); //$NON-NLS-1$
+ cmd.createArgument().setFile(this.destDir.getAbsoluteFile());
+ }
+
+ /*
+ * verbose option
+ */
+ if (this.verbose) {
+ cmd.createArgument().setValue("-verbose"); //$NON-NLS-1$
+ }
+
+ /*
+ * failnoerror option
+ */
+ if (!this.attributes.getFailonerror()) {
+ cmd.createArgument().setValue("-proceedOnError"); //$NON-NLS-1$
+ }
+
+ /*
+ * target option.
+ */
+ if (this.target != null) {
+ this.customDefaultOptions.put(CompilerOptions.OPTION_TargetPlatform, this.target);
+ }
+
+ /*
+ * source option
+ */
+ String source = this.attributes.getSource();
+ if (source != null) {
+ this.customDefaultOptions.put(CompilerOptions.OPTION_Source, source);
+ }
+
+ /*
+ * encoding option
+ */
+ if (this.encoding != null) {
+ cmd.createArgument().setValue("-encoding"); //$NON-NLS-1$
+ cmd.createArgument().setValue(this.encoding);
+ }
+
+ if (compilerArgs != null) {
+ /*
+ * Add extra argument on the command line
+ */
+ final int length = compilerArgs.length;
+ if (length != 0) {
+ for (int i = 0, max = length; i < max; i++) {
+ String arg = compilerArgs[i];
+ if (this.logFileName == null && "-log".equals(arg) && ((i + 1) < max)) { //$NON-NLS-1$
+ this.logFileName = compilerArgs[i + 1];
+ }
+ cmd.createArgument().setValue(arg);
+ }
+ }
+ }
+ /*
+ * Eclipse compiler doesn't have a -sourcepath option. This is
+ * handled through the javac task that collects all source files in
+ * srcdir option.
+ */
+ logAndAddFilesToCompile(cmd);
+ return cmd;
+ }
+
+ /**
+ * Get the compiler arguments
+ * @param javacClass
+ * @return String[] the array of arguments
+ */
+ private String[] processCompilerArguments(Class javacClass) {
+ // retrieve the method getCurrentCompilerArgs() using reflect
+ // This is done to improve the compatibility to ant 1.5
+ Method getCurrentCompilerArgsMethod = null;
+ try {
+ getCurrentCompilerArgsMethod = javacClass.getMethod("getCurrentCompilerArgs", null); //$NON-NLS-1$
+ } catch (NoSuchMethodException e) {
+ // if not found, then we cannot use this method (ant 1.5)
+ // debug level is only available with ant 1.5.x
+ }
+ String[] compilerArgs = null;
+ if (getCurrentCompilerArgsMethod != null) {
+ try {
+ compilerArgs = (String[]) getCurrentCompilerArgsMethod.invoke(this.attributes, null);
+ } catch (IllegalAccessException e) {
+ // should never happen
+ } catch (InvocationTargetException e) {
+ // should never happen
+ }
+ }
+ //check the compiler arguments for anything requiring extra processing
+ if (compilerArgs != null) checkCompilerArgs(compilerArgs);
+ return compilerArgs;
+ }
+ /**
+ * check the compiler arguments.
+ * Extract from files specified using @, lines marked with ADAPTER_PREFIX
+ * These lines specify information that needs to be interpreted by us.
+ * @param args compiler arguments to process
+ */
+ private void checkCompilerArgs(String[] args) {
+ for (int i = 0; i < args.length; i++) {
+ if (args[i].charAt(0) == '@') {
+ try {
+ char[] content = Util.getFileCharContent(new File(args[i].substring(1)), null);
+ int offset = 0;
+ int prefixLength = ADAPTER_PREFIX.length;
+ while ((offset = CharOperation.indexOf(ADAPTER_PREFIX, content, true, offset)) > -1) {
+ int start = offset + prefixLength;
+ int end = CharOperation.indexOf('\n', content, start);
+ if (end == -1)
+ end = content.length;
+ while (CharOperation.isWhitespace(content[end])) {
+ end--;
+ }
+
+ // end is inclusive, but in the API end is exclusive
+ if (CharOperation.equals(ADAPTER_ENCODING, content, start, start + ADAPTER_ENCODING.length)) {
+ CharOperation.replace(content, SEPARATOR_CHARS, File.separatorChar, start, end + 1);
+ // file or folder level custom encoding
+ start += ADAPTER_ENCODING.length;
+ int encodeStart = CharOperation.lastIndexOf('[', content, start, end);
+ if (start < encodeStart && encodeStart < end) {
+ boolean isFile = CharOperation.equals(SuffixConstants.SUFFIX_java, content, encodeStart - 5, encodeStart, false);
+
+ String str = String.valueOf(content, start, encodeStart - start);
+ String enc = String.valueOf(content, encodeStart, end - encodeStart + 1);
+ if (isFile) {
+ if (this.fileEncodings == null)
+ this.fileEncodings = new HashMap();
+ //use File to translate the string into a path with the correct File.seperator
+ this.fileEncodings.put(str, enc);
+ } else {
+ if (this.dirEncodings == null)
+ this.dirEncodings = new HashMap();
+ this.dirEncodings.put(str, enc);
+ }
+ }
+ } else if (CharOperation.equals(ADAPTER_ACCESS, content, start, start + ADAPTER_ACCESS.length)) {
+ // access rules for the classpath
+ start += ADAPTER_ACCESS.length;
+ int accessStart = CharOperation.indexOf('[', content, start, end);
+ CharOperation.replace(content, SEPARATOR_CHARS, File.separatorChar, start, accessStart);
+ if (start < accessStart && accessStart < end) {
+ String path = String.valueOf(content, start, accessStart - start);
+ String access = String.valueOf(content, accessStart, end - accessStart + 1);
+ if (this.accessRules == null)
+ this.accessRules = new ArrayList();
+ this.accessRules.add(path);
+ this.accessRules.add(access);
+ }
+ }
+ offset = end;
+ }
+ } catch (IOException e) {
+ //ignore
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Copy the classpath to the command line with access rules included.
+ * @param cmd the given command line
+ * @param classpath the given classpath entry
+ */
+ private void createClasspathArgument(Commandline cmd, Path classpath) {
+ Argument arg = cmd.createArgument();
+ final String[] pathElements = classpath.list();
+
+ // empty path return empty string
+ if (pathElements.length == 0) {
+ arg.setValue(Util.EMPTY_STRING);
+ return;
+ }
+
+ // no access rules, can set the path directly
+ if (this.accessRules == null) {
+ arg.setPath(classpath);
+ return;
+ }
+
+ int rulesLength = this.accessRules.size();
+ String[] rules = (String[]) this.accessRules.toArray(new String[rulesLength]);
+ int nextRule = 0;
+ final StringBuffer result = new StringBuffer();
+
+ //access rules are expected in the same order as the classpath, but there could
+ //be elements in the classpath not in the access rules or access rules not in the classpath
+ for (int i = 0, max = pathElements.length; i < max; i++) {
+ if (i > 0)
+ result.append(File.pathSeparatorChar);
+ String pathElement = pathElements[i];
+ result.append(pathElement);
+ //the rules list is [path, rule, path, rule, ...]
+ for (int j = nextRule; j < rulesLength; j += 2) {
+ String rule = rules[j];
+ if (pathElement.endsWith(rule)) {
+ result.append(rules[j + 1]);
+ nextRule = j + 2;
+ break;
+ }
+ // if the path doesn't match, it could be due to a trailing file separatorChar in the rule
+ if (rule.endsWith(File.separator)) {
+ // rule ends with the File.separator, but pathElement might not
+ // otherwise it would match on the first endsWith
+ int ruleLength = rule.length();
+ if (pathElement.regionMatches(false, pathElement.length() - ruleLength + 1, rule, 0, ruleLength - 1)) {
+ result.append(rules[j + 1]);
+ nextRule = j + 2;
+ break;
+ }
+ } else if (pathElement.endsWith(File.separator)) {
+ // rule doesn't end with the File.separator, but pathElement might
+ int ruleLength = rule.length();
+ if (pathElement.regionMatches(false, pathElement.length() - ruleLength - 1, rule, 0, ruleLength)) {
+ result.append(rules[j + 1]);
+ nextRule = j + 2;
+ break;
+ }
+ }
+ }
+ }
+
+ arg.setValue(result.toString());
+ }
+ /**
+ * Modified from base class, Logs the compilation parameters, adds the files
+ * to compile and logs the "niceSourceList"
+ * Appends encoding information at the end of arguments
+ *
+ * @param cmd the given command line
+ */
+ protected void logAndAddFilesToCompile(Commandline cmd) {
+ this.attributes.log("Compilation " + cmd.describeArguments(), //$NON-NLS-1$
+ Project.MSG_VERBOSE);
+
+ StringBuffer niceSourceList = new StringBuffer("File"); //$NON-NLS-1$
+ if (this.compileList.length != 1) {
+ niceSourceList.append("s"); //$NON-NLS-1$
+ }
+ niceSourceList.append(" to be compiled:"); //$NON-NLS-1$
+ niceSourceList.append(lSep);
+
+ String[] encodedFiles = null, encodedDirs = null;
+ int encodedFilesLength = 0, encodedDirsLength = 0;
+ if (this.fileEncodings != null) {
+ encodedFilesLength = this.fileEncodings.size();
+ encodedFiles = new String[encodedFilesLength];
+ this.fileEncodings.keySet().toArray(encodedFiles);
+ }
+ if (this.dirEncodings != null) {
+ encodedDirsLength = this.dirEncodings.size();
+ encodedDirs = new String[encodedDirsLength];
+ this.dirEncodings.keySet().toArray(encodedDirs);
+ //we need the directories sorted, longest first,since sub directories can
+ //override encodings for their parent directories
+ Comparator comparator = new Comparator() {
+ public int compare(Object o1, Object o2) {
+ return ((String) o2).length() - ((String) o1).length();
+ }
+ };
+ Arrays.sort(encodedDirs, comparator);
+ }
+
+ for (int i = 0; i < this.compileList.length; i++) {
+ String arg = this.compileList[i].getAbsolutePath();
+ boolean encoded = false;
+ if (encodedFiles != null) {
+ //check for file level custom encoding
+ for (int j = 0; j < encodedFilesLength; j++) {
+ if (arg.endsWith(encodedFiles[j])) {
+ //found encoding, remove it from the list to speed things up next time around
+ arg = arg + (String) this.fileEncodings.get(encodedFiles[j]);
+ if (j < encodedFilesLength - 1) {
+ System.arraycopy(encodedFiles, j + 1, encodedFiles, j, encodedFilesLength - j - 1);
+ }
+ encodedFiles[--encodedFilesLength] = null;
+ encoded = true;
+ break;
+ }
+ }
+ }
+ if (!encoded && encodedDirs != null) {
+ //check folder level custom encoding
+ for (int j = 0; j < encodedDirsLength; j++) {
+ if (arg.lastIndexOf(encodedDirs[j]) != -1) {
+ arg = arg + (String) this.dirEncodings.get(encodedDirs[j]);
+ break;
+ }
+ }
+ }
+ cmd.createArgument().setValue(arg);
+ niceSourceList.append(" " + arg + lSep); //$NON-NLS-1$
+ }
+
+ this.attributes.log(niceSourceList.toString(), Project.MSG_VERBOSE);
+ }
+}
diff --git a/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/internal/antadapter/AntAdapterMessages.java b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/internal/antadapter/AntAdapterMessages.java
new file mode 100644
index 0000000..921bf59
--- /dev/null
+++ b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/internal/antadapter/AntAdapterMessages.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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
+ * 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.antadapter;
+
+import java.text.MessageFormat;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class AntAdapterMessages {
+
+ private static final String BUNDLE_NAME = "org.eclipse.jdt.internal.antadapter.messages"; //$NON-NLS-1$
+
+ private static ResourceBundle RESOURCE_BUNDLE;
+
+ static {
+ try {
+ RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME, Locale.getDefault());
+ } catch(MissingResourceException e) {
+ System.out.println("Missing resource : " + BUNDLE_NAME.replace('.', '/') + ".properties for locale " + Locale.getDefault()); //$NON-NLS-1$//$NON-NLS-2$
+ throw e;
+ }
+ }
+
+ private AntAdapterMessages() {
+ // cannot be instantiated
+ }
+
+ public static String getString(String key) {
+ try {
+ return RESOURCE_BUNDLE.getString(key);
+ } catch (MissingResourceException e) {
+ return '!' + key + '!';
+ }
+ }
+
+ public static String getString(String key, String argument) {
+ try {
+ String message = RESOURCE_BUNDLE.getString(key);
+ MessageFormat messageFormat = new MessageFormat(message);
+ return messageFormat.format(new String[] { argument } );
+ } catch (MissingResourceException e) {
+ return '!' + key + '!';
+ }
+ }
+}
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
new file mode 100644
index 0000000..fd667c2
--- /dev/null
+++ b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/internal/antadapter/messages.properties
@@ -0,0 +1,22 @@
+###############################################################################
+# 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
+# Technical University of Berlin - extended API and implementation
+###############################################################################
+### ant tasks messages.
+ant.jdtadapter.info.usingJDTCompiler=Using JDT compiler (with extension for OT/J)
+ant.jdtadapter.error.compilationFailed=Compilation failed. Compiler errors are available in {0}
+ant.jdtadapter.error.cannotFindJDTCompiler=Cannot find the JDT compiler
+ant.jdtadapter.info.ignoringMemoryInitialSize=Since fork is false, ignoring memoryInitialSize setting
+ant.jdtadapter.info.ignoringMemoryMaximumSize=Since fork is false, ignoring memoryMaximumSize setting
+
+checkDebugAttributes.file.argument.cannot.be.null=The file argument cannot be null
+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
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/core/compiler/batch/BatchCompiler.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/core/compiler/batch/BatchCompiler.java
new file mode 100644
index 0000000..1a51c49
--- /dev/null
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/core/compiler/batch/BatchCompiler.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.compiler.batch;
+
+import java.io.PrintWriter;
+
+import org.eclipse.jdt.core.compiler.CompilationProgress;
+import org.eclipse.jdt.internal.compiler.batch.Main;
+
+/**
+ * A public API for invoking the Eclipse Compiler for Java. E.g.
+ * <pre>
+ * BatchCompiler.compile("C:\\mySources\\X.java -d C:\\myOutput", new PrintWriter(System.out), new PrintWriter(System.err), null);
+ * </pre>
+ *
+ * @since 3.4
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class BatchCompiler {
+
+ /**
+ * Invokes the Eclipse Compiler for Java with the given command line arguments, using the given writers
+ * to print messages, and reporting progress to the given compilation progress. Returns whether
+ * the compilation completed successfully.
+ * <p>
+ * Reasons for a compilation failing to complete successfully include:</p>
+ * <ul>
+ * <li>an error was reported</li>
+ * <li>a runtime exception occurred</li>
+ * <li>the compilation was canceled using the compilation progress</li>
+ * </ul>
+ * <p>
+ * The specification of the command line arguments is defined by running the batch compiler's help
+ * <pre>BatchCompiler.compile("-help", new PrintWriter(System.out), new PrintWriter(System.err), null);</pre>
+ * </p>
+ *
+ * @param commandLine the command line arguments passed to the compiler
+ * @param outWriter the writer used to print standard messages
+ * @param errWriter the writer used to print error messages
+ * @param progress the object to report progress to and to provide cancellation, or <code>null</code> if no progress is needed
+ * @return whether the compilation completed successfully
+ */
+ public static boolean compile(String commandLine, PrintWriter outWriter, PrintWriter errWriter, CompilationProgress progress) {
+ return Main.compile(Main.tokenize(commandLine), outWriter, errWriter, progress);
+ }
+
+ /**
+ * Invokes the Eclipse Compiler for Java with the given command line arguments, using the given writers
+ * to print messages, and reporting progress to the given compilation progress. Returns whether
+ * the compilation completed successfully.
+ * <p>
+ * Reasons for a compilation failing to complete successfully include:</p>
+ * <ul>
+ * <li>an error was reported</li>
+ * <li>a runtime exception occurred</li>
+ * <li>the compilation was canceled using the compilation progress</li>
+ * </ul>
+ * <p>
+ * The specification of the command line arguments is defined by running the batch compiler's help
+ * <pre>BatchCompiler.compile("-help", new PrintWriter(System.out), new PrintWriter(System.err), null);</pre>
+ * </p>
+ * Note that a <code>true</code> returned value indicates that no errors were reported, no runtime exceptions
+ * occurred and that the compilation was not canceled.
+ *
+ * @param commandLineArguments the command line arguments passed to the compiler
+ * @param outWriter the writer used to print standard messages
+ * @param errWriter the writer used to print error messages
+ * @param progress the object to report progress to and to provide cancellation, or <code>null</code> if no progress is needed
+ * @return whether the compilation completed successfully
+ */
+ public static boolean compile(String[] commandLineArguments, PrintWriter outWriter, PrintWriter errWriter, CompilationProgress progress) {
+ return Main.compile(commandLineArguments, outWriter, errWriter, progress);
+ }
+
+ private BatchCompiler() {
+ // prevent instantiation
+ }
+}
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathDirectory.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathDirectory.java
new file mode 100644
index 0000000..a592994
--- /dev/null
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathDirectory.java
@@ -0,0 +1,202 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 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
+ * $Id: ClasspathDirectory.java 23404 2010-02-03 14:10:22Z stephan $
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Fraunhofer FIRST - extended API and implementation
+ * Technical University Berlin - extended API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.batch;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.util.Hashtable;
+import java.util.List;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+import org.eclipse.jdt.internal.compiler.util.Util;
+import org.eclipse.objectteams.otdt.internal.core.compiler.control.Config;
+
+/**
+ * MIGRATION_STATUS: 3.3
+ *
+ * OTDT changes:
+ * What: allow batch compiler to force mode == SOURCE
+ * Why: getTeamOfRoleFile may require a source team.
+ *
+ * @version $Id: ClasspathDirectory.java 23404 2010-02-03 14:10:22Z stephan $
+ */
+public class ClasspathDirectory extends ClasspathLocation {
+
+private Hashtable directoryCache;
+private String[] missingPackageHolder = new String[1];
+private int mode; // ability to only consider one kind of files (source vs. binaries), by default use both
+private String encoding; // only useful if referenced in the source path
+
+ClasspathDirectory(File directory, String encoding, int mode,
+ AccessRuleSet accessRuleSet, String destinationPath) {
+ super(accessRuleSet, destinationPath);
+ this.mode = mode;
+ try {
+ this.path = directory.getCanonicalPath();
+ } catch (IOException e) {
+ // should not happen as we know that the file exists
+ this.path = directory.getAbsolutePath();
+ }
+ if (!this.path.endsWith(File.separator))
+ this.path += File.separator;
+ this.directoryCache = new Hashtable(11);
+ this.encoding = encoding;
+}
+String[] directoryList(String qualifiedPackageName) {
+ String[] dirList = (String[]) this.directoryCache.get(qualifiedPackageName);
+ if (dirList == this.missingPackageHolder) return null; // package exists in another classpath directory or jar
+ if (dirList != null) return dirList;
+
+ File dir = new File(this.path + qualifiedPackageName);
+ notFound : if (dir.isDirectory()) {
+ // must protect against a case insensitive File call
+ // walk the qualifiedPackageName backwards looking for an uppercase character before the '/'
+ int index = qualifiedPackageName.length();
+ int last = qualifiedPackageName.lastIndexOf(File.separatorChar);
+ while (--index > last && !ScannerHelper.isUpperCase(qualifiedPackageName.charAt(index))){/*empty*/}
+ if (index > last) {
+ if (last == -1) {
+ if (!doesFileExist(qualifiedPackageName, Util.EMPTY_STRING))
+ break notFound;
+ } else {
+ String packageName = qualifiedPackageName.substring(last + 1);
+ String parentPackage = qualifiedPackageName.substring(0, last);
+ if (!doesFileExist(packageName, parentPackage))
+ break notFound;
+ }
+ }
+ if ((dirList = dir.list()) == null)
+ dirList = CharOperation.NO_STRINGS;
+ this.directoryCache.put(qualifiedPackageName, dirList);
+ return dirList;
+ }
+ this.directoryCache.put(qualifiedPackageName, this.missingPackageHolder);
+ return null;
+}
+boolean doesFileExist(String fileName, String qualifiedPackageName) {
+ String[] dirList = directoryList(qualifiedPackageName);
+ if (dirList == null) return false; // most common case
+
+ for (int i = dirList.length; --i >= 0;)
+ if (fileName.equals(dirList[i]))
+ return true;
+ return false;
+}
+public List fetchLinkedJars(FileSystem.ClasspathSectionProblemReporter problemReporter) {
+ return null;
+}
+public NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String qualifiedBinaryFileName) {
+ return findClass(typeName, qualifiedPackageName, qualifiedBinaryFileName, false);
+}
+public NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String qualifiedBinaryFileName, boolean asBinaryOnly) {
+ if (!isPackage(qualifiedPackageName)) return null; // most common case
+
+//{ObjectTeams: make configurable via Dependencies:
+ int adjustedMode = this.mode;
+ if (Config.getSourceTypeRequired())
+ adjustedMode = SOURCE;
+// SH}
+
+ String fileName = new String(typeName);
+//{ObjectTeams: was "this.mode" instead of adjustedMode
+ boolean binaryExists = ((adjustedMode & BINARY) != 0) && doesFileExist(fileName + SUFFIX_STRING_class, qualifiedPackageName);
+ boolean sourceExists = ((adjustedMode & SOURCE) != 0) && doesFileExist(fileName + SUFFIX_STRING_java, qualifiedPackageName);
+// SH}
+ if (sourceExists && !asBinaryOnly) {
+ String fullSourcePath = this.path + qualifiedBinaryFileName.substring(0, qualifiedBinaryFileName.length() - 6) + SUFFIX_STRING_java;
+ if (!binaryExists)
+ return new NameEnvironmentAnswer(new CompilationUnit(null,
+ fullSourcePath, this.encoding, this.destinationPath),
+ fetchAccessRestriction(qualifiedBinaryFileName));
+ String fullBinaryPath = this.path + qualifiedBinaryFileName;
+ long binaryModified = new File(fullBinaryPath).lastModified();
+ long sourceModified = new File(fullSourcePath).lastModified();
+ if (sourceModified > binaryModified)
+ return new NameEnvironmentAnswer(new CompilationUnit(null,
+ fullSourcePath, this.encoding, this.destinationPath),
+ fetchAccessRestriction(qualifiedBinaryFileName));
+ }
+ if (binaryExists) {
+ try {
+ ClassFileReader reader = ClassFileReader.read(this.path + qualifiedBinaryFileName);
+ if (reader != null)
+ return new NameEnvironmentAnswer(
+ reader,
+ fetchAccessRestriction(qualifiedBinaryFileName));
+ } catch (IOException e) {
+ // treat as if file is missing
+ } catch (ClassFormatException e) {
+ // treat as if file is missing
+ }
+ }
+ return null;
+}
+public char[][][] findTypeNames(String qualifiedPackageName) {
+ if (!isPackage(qualifiedPackageName)) {
+ return null; // most common case
+ }
+ File dir = new File(this.path + qualifiedPackageName);
+ if (!dir.exists() || !dir.isDirectory()) {
+ return null;
+ }
+ String[] listFiles = dir.list(new FilenameFilter() {
+ public boolean accept(File directory, String name) {
+ String fileName = name.toLowerCase();
+ return fileName.endsWith(".class") || fileName.endsWith(".java"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ });
+ int length;
+ if (listFiles == null || (length = listFiles.length) == 0) {
+ return null;
+ }
+ char[][][] result = new char[length][][];
+ char[][] packageName = CharOperation.splitOn(File.separatorChar, qualifiedPackageName.toCharArray());
+ for (int i = 0; i < length; i++) {
+ String fileName = listFiles[i];
+ int indexOfLastDot = fileName.indexOf('.');
+ result[i] = CharOperation.arrayConcat(packageName, fileName.substring(0, indexOfLastDot).toCharArray());
+ }
+ return result;
+}
+public void initialize() throws IOException {
+ // nothing to do
+}
+public boolean isPackage(String qualifiedPackageName) {
+ return directoryList(qualifiedPackageName) != null;
+}
+public void reset() {
+ this.directoryCache = new Hashtable(11);
+}
+public String toString() {
+ return "ClasspathDirectory " + this.path; //$NON-NLS-1$
+}
+public char[] normalizedPath() {
+ if (this.normalizedPath == null) {
+ this.normalizedPath = this.path.toCharArray();
+ if (File.separatorChar == '\\') {
+ CharOperation.replace(this.normalizedPath, '\\', '/');
+ }
+ }
+ return this.normalizedPath;
+}
+public String getPath() {
+ return this.path;
+}
+}
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJar.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJar.java
new file mode 100644
index 0000000..2ed77f1
--- /dev/null
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJar.java
@@ -0,0 +1,205 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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
+ * 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.batch;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
+import org.eclipse.jdt.internal.compiler.util.ManifestAnalyzer;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class ClasspathJar extends ClasspathLocation {
+
+protected File file;
+protected ZipFile zipFile;
+protected boolean closeZipFileAtEnd;
+protected Hashtable packageCache;
+
+public ClasspathJar(File file, boolean closeZipFileAtEnd,
+ AccessRuleSet accessRuleSet, String destinationPath) {
+ super(accessRuleSet, destinationPath);
+ this.file = file;
+ this.closeZipFileAtEnd = closeZipFileAtEnd;
+}
+
+public List fetchLinkedJars(FileSystem.ClasspathSectionProblemReporter problemReporter) {
+ // expected to be called once only - if multiple calls desired, consider
+ // using a cache
+ InputStream inputStream = null;
+ try {
+ initialize();
+ ArrayList result = new ArrayList();
+ ZipEntry manifest = this.zipFile.getEntry("META-INF/MANIFEST.MF"); //$NON-NLS-1$
+ if (manifest != null) { // non-null implies regular file
+ inputStream = this.zipFile.getInputStream(manifest);
+ ManifestAnalyzer analyzer = new ManifestAnalyzer();
+ boolean success = analyzer.analyzeManifestContents(inputStream);
+ List calledFileNames = analyzer.getCalledFileNames();
+ if (problemReporter != null) {
+ if (!success || analyzer.getClasspathSectionsCount() == 1 && calledFileNames == null) {
+ problemReporter.invalidClasspathSection(getPath());
+ } else if (analyzer.getClasspathSectionsCount() > 1) {
+ problemReporter.multipleClasspathSections(getPath());
+ }
+ }
+ if (calledFileNames != null) {
+ Iterator calledFilesIterator = calledFileNames.iterator();
+ String directoryPath = getPath();
+ int lastSeparator = directoryPath.lastIndexOf(File.separatorChar);
+ directoryPath = directoryPath.substring(0, lastSeparator + 1); // potentially empty (see bug 214731)
+ while (calledFilesIterator.hasNext()) {
+ result.add(new ClasspathJar(new File(directoryPath + (String) calledFilesIterator.next()), this.closeZipFileAtEnd, this.accessRuleSet, this.destinationPath));
+ }
+ }
+ }
+ return result;
+ } catch (IOException e) {
+ return null;
+ } finally {
+ if (inputStream != null) {
+ try {
+ inputStream.close();
+ } catch (IOException e) {
+ // best effort
+ }
+ }
+ }
+}
+public NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String qualifiedBinaryFileName) {
+ return findClass(typeName, qualifiedPackageName, qualifiedBinaryFileName, false);
+}
+public NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String qualifiedBinaryFileName, boolean asBinaryOnly) {
+ if (!isPackage(qualifiedPackageName))
+ return null; // most common case
+
+ try {
+ ClassFileReader reader = ClassFileReader.read(this.zipFile, qualifiedBinaryFileName);
+ if (reader != null)
+ return new NameEnvironmentAnswer(reader, fetchAccessRestriction(qualifiedBinaryFileName));
+ } catch(ClassFormatException e) {
+ // treat as if class file is missing
+ } catch (IOException e) {
+ // treat as if class file is missing
+ }
+ return null;
+}
+public char[][][] findTypeNames(String qualifiedPackageName) {
+ if (!isPackage(qualifiedPackageName))
+ return null; // most common case
+
+ ArrayList answers = new ArrayList();
+ nextEntry : for (Enumeration e = this.zipFile.entries(); e.hasMoreElements(); ) {
+ String fileName = ((ZipEntry) e.nextElement()).getName();
+
+ // add the package name & all of its parent packages
+ int last = fileName.lastIndexOf('/');
+ while (last > 0) {
+ // extract the package name
+ String packageName = fileName.substring(0, last);
+ if (!qualifiedPackageName.equals(packageName))
+ continue nextEntry;
+ int indexOfDot = fileName.lastIndexOf('.');
+ if (indexOfDot != -1) {
+ String typeName = fileName.substring(last + 1, indexOfDot);
+ char[] packageArray = packageName.toCharArray();
+ answers.add(
+ CharOperation.arrayConcat(
+ CharOperation.splitOn('/', packageArray),
+ typeName.toCharArray()));
+ }
+ }
+ }
+ int size = answers.size();
+ if (size != 0) {
+ char[][][] result = new char[size][][];
+ answers.toArray(result);
+ return null;
+ }
+ return null;
+}
+public void initialize() throws IOException {
+ if (this.zipFile == null) {
+ this.zipFile = new ZipFile(this.file);
+ }
+}
+public boolean isPackage(String qualifiedPackageName) {
+ if (this.packageCache != null)
+ return this.packageCache.containsKey(qualifiedPackageName);
+
+ this.packageCache = new Hashtable(41);
+ this.packageCache.put(Util.EMPTY_STRING, Util.EMPTY_STRING);
+
+ nextEntry : for (Enumeration e = this.zipFile.entries(); e.hasMoreElements(); ) {
+ String fileName = ((ZipEntry) e.nextElement()).getName();
+
+ // add the package name & all of its parent packages
+ int last = fileName.lastIndexOf('/');
+ while (last > 0) {
+ // extract the package name
+ String packageName = fileName.substring(0, last);
+ if (this.packageCache.containsKey(packageName))
+ continue nextEntry;
+ this.packageCache.put(packageName, packageName);
+ last = packageName.lastIndexOf('/');
+ }
+ }
+ return this.packageCache.containsKey(qualifiedPackageName);
+}
+public void reset() {
+ if (this.zipFile != null && this.closeZipFileAtEnd) {
+ try {
+ this.zipFile.close();
+ } catch(IOException e) {
+ // ignore
+ }
+ this.zipFile = null;
+ }
+ this.packageCache = null;
+}
+public String toString() {
+ return "Classpath for jar file " + this.file.getPath(); //$NON-NLS-1$
+}
+public char[] normalizedPath() {
+ if (this.normalizedPath == null) {
+ String path2 = this.getPath();
+ char[] rawName = path2.toCharArray();
+ if (File.separatorChar == '\\') {
+ CharOperation.replace(rawName, '\\', '/');
+ }
+ this.normalizedPath = CharOperation.subarray(rawName, 0, CharOperation.lastIndexOf('.', rawName));
+ }
+ return this.normalizedPath;
+}
+public String getPath() {
+ if (this.path == null) {
+ try {
+ this.path = this.file.getCanonicalPath();
+ } catch (IOException e) {
+ // in case of error, simply return the absolute path
+ this.path = this.file.getAbsolutePath();
+ }
+ }
+ return this.path;
+}
+}
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathLocation.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathLocation.java
new file mode 100644
index 0000000..700ffca
--- /dev/null
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathLocation.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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.batch;
+
+import java.io.File;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+
+public abstract class ClasspathLocation implements FileSystem.Classpath,
+ SuffixConstants {
+
+ public static final int SOURCE = 1;
+ public static final int BINARY = 2;
+
+ String path;
+ char[] normalizedPath;
+ public AccessRuleSet accessRuleSet;
+
+ public String destinationPath;
+ // destination path for compilation units that are reached through this
+ // classpath location; the coding is consistent with the one of
+ // Main.destinationPath:
+ // == null: unspecified, use whatever value is set by the enclosing
+ // context, id est Main;
+ // == Main.NONE: absorbent element, do not output class files;
+ // else: use as the path of the directory into which class files must
+ // be written.
+ // potentially carried by any entry that contains to be compiled files
+
+ protected ClasspathLocation(AccessRuleSet accessRuleSet,
+ String destinationPath) {
+ this.accessRuleSet = accessRuleSet;
+ this.destinationPath = destinationPath;
+ }
+
+ /**
+ * Return the first access rule which is violated when accessing a given
+ * type, or null if no 'non accessible' access rule applies.
+ *
+ * @param qualifiedBinaryFileName
+ * tested type specification, formed as:
+ * "org/eclipse/jdt/core/JavaCore.class"; on systems that
+ * use \ as File.separator, the
+ * "org\eclipse\jdt\core\JavaCore.class" is accepted as well
+ * @return the first access rule which is violated when accessing a given
+ * type, or null if none applies
+ */
+ protected AccessRestriction fetchAccessRestriction(String qualifiedBinaryFileName) {
+ if (this.accessRuleSet == null)
+ return null;
+ char [] qualifiedTypeName = qualifiedBinaryFileName.
+ substring(0, qualifiedBinaryFileName.length() - SUFFIX_CLASS.length)
+ .toCharArray();
+ if (File.separatorChar == '\\') {
+ CharOperation.replace(qualifiedTypeName, File.separatorChar, '/');
+ }
+ return this.accessRuleSet.getViolatedRestriction(qualifiedTypeName);
+ }
+}
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathSourceJar.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathSourceJar.java
new file mode 100644
index 0000000..0629410
--- /dev/null
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathSourceJar.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * 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
+ * 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.batch;
+
+import java.io.File;
+import java.io.InputStream;
+import java.io.IOException;
+import java.util.zip.ZipEntry;
+
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class ClasspathSourceJar extends ClasspathJar {
+ private String encoding;
+
+ public ClasspathSourceJar(File file, boolean closeZipFileAtEnd,
+ AccessRuleSet accessRuleSet, String encoding,
+ String destinationPath) {
+ super(file, closeZipFileAtEnd, accessRuleSet, destinationPath);
+ this.encoding = encoding;
+ }
+
+ public NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String qualifiedBinaryFileName, boolean asBinaryOnly) {
+ if (!isPackage(qualifiedPackageName))
+ return null; // most common case
+
+ ZipEntry sourceEntry = this.zipFile.getEntry(qualifiedBinaryFileName.substring(0, qualifiedBinaryFileName.length() - 6) + SUFFIX_STRING_java);
+ if (sourceEntry != null) {
+ try {
+ InputStream stream = null;
+ char[] contents = null;
+ try {
+ stream = this.zipFile.getInputStream(sourceEntry);
+ contents = Util.getInputStreamAsCharArray(stream, -1, this.encoding);
+ } finally {
+ if (stream != null)
+ stream.close();
+ }
+ return new NameEnvironmentAnswer(
+ new CompilationUnit(
+ contents,
+ qualifiedBinaryFileName.substring(0, qualifiedBinaryFileName.length() - 6) + SUFFIX_STRING_java,
+ this.encoding,
+ this.destinationPath),
+ fetchAccessRestriction(qualifiedBinaryFileName));
+ } catch (IOException e) {
+ // treat as if source file is missing
+ }
+ }
+ return null;
+ }
+ public NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String qualifiedBinaryFileName) {
+ return findClass(typeName, qualifiedPackageName, qualifiedBinaryFileName, false);
+ }
+}
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
new file mode 100644
index 0000000..e6986b4
--- /dev/null
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/CompilationUnit.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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
+ * 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.batch;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilationUnit;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class CompilationUnit implements ICompilationUnit {
+ public char[] contents;
+ public char[] fileName;
+ public char[] mainTypeName;
+ String encoding;
+ public String destinationPath;
+ // a specific destination path for this compilation unit; coding is
+ // aligned with Main.destinationPath:
+ // == null: unspecified, use whatever value is set by the enclosing
+ // context, id est Main;
+ // == Main.NONE: absorbent element, do not output class files;
+ // else: use as the path of the directory into which class files must
+ // be written.
+
+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 = contents;
+ char[] fileNameCharArray = fileName.toCharArray();
+ switch(File.separatorChar) {
+ case '/' :
+ if (CharOperation.indexOf('\\', fileNameCharArray) != -1) {
+ CharOperation.replace(fileNameCharArray, '\\', '/');
+ }
+ break;
+ case '\\' :
+ if (CharOperation.indexOf('/', fileNameCharArray) != -1) {
+ CharOperation.replace(fileNameCharArray, '/', '\\');
+ }
+ }
+ this.fileName = fileNameCharArray;
+ int start = CharOperation.lastIndexOf(File.separatorChar, fileNameCharArray) + 1;
+
+ int end = CharOperation.lastIndexOf('.', fileNameCharArray);
+ if (end == -1) {
+ end = fileNameCharArray.length;
+ }
+
+ this.mainTypeName = CharOperation.subarray(fileNameCharArray, start, end);
+ this.encoding = encoding;
+ this.destinationPath = destinationPath;
+}
+public char[] getContents() {
+ if (this.contents != null)
+ return this.contents; // answer the cached source
+
+ // otherwise retrieve it
+ try {
+ return Util.getFileCharContent(new File(new String(this.fileName)), this.encoding);
+ } catch (IOException e) {
+ this.contents = CharOperation.NO_CHAR; // assume no source if asked again
+ throw new AbortCompilationUnit(null, e, this.encoding);
+ }
+}
+/**
+ * @see org.eclipse.jdt.internal.compiler.env.IDependent#getFileName()
+ */
+public char[] getFileName() {
+ return this.fileName;
+}
+public char[] getMainTypeName() {
+ return this.mainTypeName;
+}
+public char[][] getPackageName() {
+ return null;
+}
+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/FileFinder.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileFinder.java
new file mode 100644
index 0000000..7fb2c63
--- /dev/null
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileFinder.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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
+ * 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.batch;
+
+import java.io.File;
+import java.util.ArrayList;
+
+public class FileFinder {
+
+public static String[] find(File f, String pattern) {
+ ArrayList files = new ArrayList();
+ find0(f, pattern, files);
+ String[] result = new String[files.size()];
+ files.toArray(result);
+ return result;
+}
+private static void find0(File f, String pattern, ArrayList collector) {
+ if (f.isDirectory()) {
+ String[] files = f.list();
+ if (files == null) return;
+ for (int i = 0, max = files.length; i < max; i++) {
+ File current = new File(f, files[i]);
+ if (current.isDirectory()) {
+ find0(current, pattern, collector);
+ } else {
+ if (current.getName().toUpperCase().endsWith(pattern)) {
+ collector.add(current.getAbsolutePath());
+ }
+ }
+ }
+ }
+}
+}
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java
new file mode 100644
index 0000000..74c99f3
--- /dev/null
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java
@@ -0,0 +1,356 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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
+ * 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.batch;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
+import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class FileSystem implements INameEnvironment, SuffixConstants {
+ public interface Classpath {
+ char[][][] findTypeNames(String qualifiedPackageName);
+ NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String qualifiedBinaryFileName);
+ NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String qualifiedBinaryFileName, boolean asBinaryOnly);
+ boolean isPackage(String qualifiedPackageName);
+ /**
+ * Return a list of the jar file names defined in the Class-Path section
+ * of the jar file manifest if any, null else. Only ClasspathJar (and
+ * extending classes) instances may return a non-null result.
+ * @param problemReporter problem reporter with which potential
+ * misconfiguration issues are raised
+ * @return a list of the jar file names defined in the Class-Path
+ * section of the jar file manifest if any
+ */
+ List fetchLinkedJars(ClasspathSectionProblemReporter problemReporter);
+ /**
+ * This method resets the environment. The resulting state is equivalent to
+ * a new name environment without creating a new object.
+ */
+ void reset();
+ /**
+ * Return a normalized path for file based classpath entries. This is an
+ * absolute path in which file separators are transformed to the
+ * platform-agnostic '/', ending with a '/' for directories. This is an
+ * absolute path in which file separators are transformed to the
+ * platform-agnostic '/', deprived from the '.jar' (resp. '.zip')
+ * extension for jar (resp. zip) files.
+ * @return a normalized path for file based classpath entries
+ */
+ char[] normalizedPath();
+ /**
+ * Return the path for file based classpath entries. This is an absolute path
+ * ending with a file separator for directories, an absolute path including the '.jar'
+ * (resp. '.zip') extension for jar (resp. zip) files.
+ * @return the path for file based classpath entries
+ */
+ String getPath();
+ /**
+ * Initialize the entry
+ */
+ void initialize() throws IOException;
+ }
+ public interface ClasspathSectionProblemReporter {
+ void invalidClasspathSection(String jarFilePath);
+ void multipleClasspathSections(String jarFilePath);
+ }
+
+ /**
+ * This class is defined how to normalize the classpath entries.
+ * It removes duplicate entries.
+ */
+ public static class ClasspathNormalizer {
+ /**
+ * Returns the normalized classpath entries (no duplicate).
+ * <p>The given classpath entries are FileSystem.Classpath. We check the getPath() in order to find
+ * duplicate entries.</p>
+ *
+ * @param classpaths the given classpath entries
+ * @return the normalized classpath entries
+ */
+ public static ArrayList normalize(ArrayList classpaths) {
+ ArrayList normalizedClasspath = new ArrayList();
+ HashSet cache = new HashSet();
+ for (Iterator iterator = classpaths.iterator(); iterator.hasNext(); ) {
+ FileSystem.Classpath classpath = (FileSystem.Classpath) iterator.next();
+ String path = classpath.getPath();
+ if (!cache.contains(path)) {
+ normalizedClasspath.add(classpath);
+ cache.add(path);
+ }
+ }
+ return normalizedClasspath;
+ }
+ }
+
+ Classpath[] classpaths;
+ Set knownFileNames;
+
+/*
+ classPathNames is a collection is Strings representing the full path of each class path
+ initialFileNames is a collection is Strings, the trailing '.java' will be removed if its not already.
+*/
+public FileSystem(String[] classpathNames, String[] initialFileNames, String encoding) {
+ final int classpathSize = classpathNames.length;
+ this.classpaths = new Classpath[classpathSize];
+ int counter = 0;
+ for (int i = 0; i < classpathSize; i++) {
+ Classpath classpath = getClasspath(classpathNames[i], encoding, null);
+ try {
+ classpath.initialize();
+ this.classpaths[counter++] = classpath;
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ if (counter != classpathSize) {
+ System.arraycopy(this.classpaths, 0, (this.classpaths = new Classpath[counter]), 0, counter);
+ }
+ initializeKnownFileNames(initialFileNames);
+}
+FileSystem(Classpath[] paths, String[] initialFileNames) {
+ final int length = paths.length;
+ int counter = 0;
+ this.classpaths = new FileSystem.Classpath[length];
+ for (int i = 0; i < length; i++) {
+ final Classpath classpath = paths[i];
+ try {
+ classpath.initialize();
+ this.classpaths[counter++] = classpath;
+ } catch(IOException exception) {
+ // ignore
+ }
+ }
+ if (counter != length) {
+ // should not happen
+ System.arraycopy(this.classpaths, 0, (this.classpaths = new FileSystem.Classpath[counter]), 0, counter);
+ }
+ initializeKnownFileNames(initialFileNames);
+}
+public static Classpath getClasspath(String classpathName, String encoding, AccessRuleSet accessRuleSet) {
+ return getClasspath(classpathName, encoding, false, accessRuleSet, null);
+}
+public static Classpath getClasspath(String classpathName, String encoding,
+ boolean isSourceOnly, AccessRuleSet accessRuleSet,
+ String destinationPath) {
+ Classpath result = null;
+ File file = new File(convertPathSeparators(classpathName));
+ if (file.isDirectory()) {
+ if (file.exists()) {
+ result = new ClasspathDirectory(file, encoding,
+ isSourceOnly ? ClasspathLocation.SOURCE :
+ ClasspathLocation.SOURCE | ClasspathLocation.BINARY,
+ accessRuleSet,
+ destinationPath == null || destinationPath == Main.NONE ?
+ destinationPath : // keep == comparison valid
+ convertPathSeparators(destinationPath));
+ }
+ } else {
+ if (Util.isPotentialZipArchive(classpathName)) {
+ if (isSourceOnly) {
+ // source only mode
+ result = new ClasspathSourceJar(file, true, accessRuleSet,
+ encoding,
+ destinationPath == null || destinationPath == Main.NONE ?
+ destinationPath : // keep == comparison valid
+ convertPathSeparators(destinationPath));
+ } else if (destinationPath == null) {
+ // class file only mode
+ result = new ClasspathJar(file, true, accessRuleSet, null);
+ }
+ }
+ }
+ return result;
+}
+private void initializeKnownFileNames(String[] initialFileNames) {
+ if (initialFileNames == null) {
+ this.knownFileNames = new HashSet(0);
+ return;
+ }
+ this.knownFileNames = new HashSet(initialFileNames.length * 2);
+ for (int i = initialFileNames.length; --i >= 0;) {
+ File compilationUnitFile = new File(initialFileNames[i]);
+ char[] fileName = null;
+ try {
+ fileName = compilationUnitFile.getCanonicalPath().toCharArray();
+ } catch (IOException e) {
+ // this should not happen as the file exists
+ continue;
+ }
+ char[] matchingPathName = null;
+ final int lastIndexOf = CharOperation.lastIndexOf('.', fileName);
+ if (lastIndexOf != -1) {
+ fileName = CharOperation.subarray(fileName, 0, lastIndexOf);
+ }
+ CharOperation.replace(fileName, '\\', '/');
+ for (int j = 0, max = this.classpaths.length; j < max; j++) {
+ char[] matchCandidate = this.classpaths[j].normalizedPath();
+ if (this.classpaths[j] instanceof ClasspathDirectory &&
+ CharOperation.prefixEquals(matchCandidate, fileName) &&
+ (matchingPathName == null ||
+ matchCandidate.length < matchingPathName.length)) {
+ matchingPathName = matchCandidate;
+ }
+ }
+ if (matchingPathName == null) {
+ this.knownFileNames.add(new String(fileName)); // leave as is...
+ } else {
+ this.knownFileNames.add(new String(CharOperation.subarray(fileName, matchingPathName.length, fileName.length)));
+ }
+ matchingPathName = null;
+ }
+}
+public void cleanup() {
+ for (int i = 0, max = this.classpaths.length; i < max; i++)
+ this.classpaths[i].reset();
+}
+private static String convertPathSeparators(String path) {
+ return File.separatorChar == '/'
+ ? path.replace('\\', '/')
+ : path.replace('/', '\\');
+}
+private NameEnvironmentAnswer findClass(String qualifiedTypeName, char[] typeName, boolean asBinaryOnly){
+ if (this.knownFileNames.contains(qualifiedTypeName)) return null; // looking for a file which we know was provided at the beginning of the compilation
+
+ String qualifiedBinaryFileName = qualifiedTypeName + SUFFIX_STRING_class;
+ String qualifiedPackageName =
+ qualifiedTypeName.length() == typeName.length
+ ? Util.EMPTY_STRING
+ : qualifiedBinaryFileName.substring(0, qualifiedTypeName.length() - typeName.length - 1);
+ String qp2 = File.separatorChar == '/' ? qualifiedPackageName : qualifiedPackageName.replace('/', File.separatorChar);
+ NameEnvironmentAnswer suggestedAnswer = null;
+ if (qualifiedPackageName == qp2) {
+ for (int i = 0, length = this.classpaths.length; i < length; i++) {
+ NameEnvironmentAnswer answer = this.classpaths[i].findClass(typeName, qualifiedPackageName, qualifiedBinaryFileName, asBinaryOnly);
+ if (answer != null) {
+ if (!answer.ignoreIfBetter()) {
+ if (answer.isBetter(suggestedAnswer))
+ return answer;
+ } else if (answer.isBetter(suggestedAnswer))
+ // remember suggestion and keep looking
+ suggestedAnswer = answer;
+ }
+ }
+ } else {
+ String qb2 = qualifiedBinaryFileName.replace('/', File.separatorChar);
+ for (int i = 0, length = this.classpaths.length; i < length; i++) {
+ Classpath p = this.classpaths[i];
+ NameEnvironmentAnswer answer = (p instanceof ClasspathJar)
+ ? p.findClass(typeName, qualifiedPackageName, qualifiedBinaryFileName, asBinaryOnly)
+ : p.findClass(typeName, qp2, qb2, asBinaryOnly);
+ if (answer != null) {
+ if (!answer.ignoreIfBetter()) {
+ if (answer.isBetter(suggestedAnswer))
+ return answer;
+ } else if (answer.isBetter(suggestedAnswer))
+ // remember suggestion and keep looking
+ suggestedAnswer = answer;
+ }
+ }
+ }
+ if (suggestedAnswer != null)
+ // no better answer was found
+ return suggestedAnswer;
+ return null;
+}
+public NameEnvironmentAnswer findType(char[][] compoundName) {
+ if (compoundName != null)
+ return findClass(
+ new String(CharOperation.concatWith(compoundName, '/')),
+ compoundName[compoundName.length - 1],
+ false);
+ return null;
+}
+public char[][][] findTypeNames(char[][] packageName) {
+ char[][][] result = null;
+ if (packageName != null) {
+ String qualifiedPackageName = new String(CharOperation.concatWith(packageName, '/'));
+ String qualifiedPackageName2 = File.separatorChar == '/' ? qualifiedPackageName : qualifiedPackageName.replace('/', File.separatorChar);
+ if (qualifiedPackageName == qualifiedPackageName2) {
+ for (int i = 0, length = this.classpaths.length; i < length; i++) {
+ char[][][] answers = this.classpaths[i].findTypeNames(qualifiedPackageName);
+ if (answers != null) {
+ // concat with previous answers
+ if (result == null) {
+ result = answers;
+ } else {
+ int resultLength = result.length;
+ int answersLength = answers.length;
+ System.arraycopy(result, 0, (result = new char[answersLength + resultLength][][]), 0, resultLength);
+ System.arraycopy(answers, 0, result, resultLength, answersLength);
+ }
+ }
+ }
+ } else {
+ for (int i = 0, length = this.classpaths.length; i < length; i++) {
+ Classpath p = this.classpaths[i];
+ char[][][] answers = (p instanceof ClasspathJar)
+ ? p.findTypeNames(qualifiedPackageName)
+ : p.findTypeNames(qualifiedPackageName2);
+ if (answers != null) {
+ // concat with previous answers
+ if (result == null) {
+ result = answers;
+ } else {
+ int resultLength = result.length;
+ int answersLength = answers.length;
+ System.arraycopy(result, 0, (result = new char[answersLength + resultLength][][]), 0, resultLength);
+ System.arraycopy(answers, 0, result, resultLength, answersLength);
+ }
+ }
+ }
+ }
+ }
+ return result;
+}
+public NameEnvironmentAnswer findType(char[][] compoundName, boolean asBinaryOnly) {
+ if (compoundName != null)
+ return findClass(
+ new String(CharOperation.concatWith(compoundName, '/')),
+ compoundName[compoundName.length - 1],
+ asBinaryOnly);
+ return null;
+}
+public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName) {
+ if (typeName != null)
+ return findClass(
+ new String(CharOperation.concatWith(packageName, typeName, '/')),
+ typeName,
+ false);
+ return null;
+}
+public boolean isPackage(char[][] compoundName, char[] packageName) {
+ String qualifiedPackageName = new String(CharOperation.concatWith(compoundName, packageName, '/'));
+ String qp2 = File.separatorChar == '/' ? qualifiedPackageName : qualifiedPackageName.replace('/', File.separatorChar);
+ if (qualifiedPackageName == qp2) {
+ for (int i = 0, length = this.classpaths.length; i < length; i++)
+ if (this.classpaths[i].isPackage(qualifiedPackageName))
+ return true;
+ } else {
+ for (int i = 0, length = this.classpaths.length; i < length; i++) {
+ Classpath p = this.classpaths[i];
+ if ((p instanceof ClasspathJar) ? p.isPackage(qualifiedPackageName) : p.isPackage(qp2))
+ return true;
+ }
+ }
+ return false;
+}
+}
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
new file mode 100644
index 0000000..a81f87a
--- /dev/null
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
@@ -0,0 +1,4416 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 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
+ * Tom Tromey - Contribution for bug 125961
+ * Tom Tromey - Contribution for bug 159641
+ * Benjamin Muskalla - Contribution for bug 239066
+ * Stephan Herrmann - Contribution for bug 236385
+ * Fraunhofer FIRST - extended API and implementation
+ * Technical University Berlin - extended API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.batch;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.LineNumberReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Field;
+import java.text.DateFormat;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.CompilationProgress;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.core.compiler.batch.BatchCompiler;
+import org.eclipse.jdt.internal.compiler.AbstractAnnotationProcessorManager;
+import org.eclipse.jdt.internal.compiler.ClassFile;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.Compiler;
+import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
+import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
+import org.eclipse.jdt.internal.compiler.IProblemFactory;
+import org.eclipse.jdt.internal.compiler.batch.FileSystem.Classpath;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.env.AccessRule;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.impl.CompilerStats;
+import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
+import org.eclipse.jdt.internal.compiler.util.GenericXMLWriter;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfInt;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
+import org.eclipse.jdt.internal.compiler.util.Messages;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+/**
+ * OTDT changes:
+ * What:
+ * + set different error codes for normal exit vs. thrown exceptions.
+ * + store all encountered problems (warnings and errors)
+ * How:
+ * + interpret IProblem.Unclassified as a caught Exception
+ * + store them in a vector
+ * Why:
+ * + error evaluation by the test suite.
+ *
+ * What:
+ * + more info for -version.
+ *
+ * What:
+ * + Support configuration of OT-specific warnings.
+ *
+ * What:
+ * + Respect role files when computing the output path (fewer directory prefixes)
+ */
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class Main implements ProblemSeverities, SuffixConstants {
+ public static class Logger {
+ private PrintWriter err;
+ private PrintWriter log;
+ private Main main;
+ private PrintWriter out;
+ private HashMap parameters;
+ int tagBits;
+ private static final String CLASS = "class"; //$NON-NLS-1$
+ private static final String CLASS_FILE = "classfile"; //$NON-NLS-1$
+ private static final String CLASSPATH = "classpath"; //$NON-NLS-1$
+ private static final String CLASSPATH_FILE = "FILE"; //$NON-NLS-1$
+ private static final String CLASSPATH_FOLDER = "FOLDER"; //$NON-NLS-1$
+ private static final String CLASSPATH_ID = "id"; //$NON-NLS-1$
+ private static final String CLASSPATH_JAR = "JAR"; //$NON-NLS-1$
+ private static final String CLASSPATHS = "classpaths"; //$NON-NLS-1$
+ private static final String COMMAND_LINE_ARGUMENT = "argument"; //$NON-NLS-1$
+ private static final String COMMAND_LINE_ARGUMENTS = "command_line"; //$NON-NLS-1$
+ private static final String COMPILER = "compiler"; //$NON-NLS-1$
+ private static final String COMPILER_COPYRIGHT = "copyright"; //$NON-NLS-1$
+ private static final String COMPILER_NAME = "name"; //$NON-NLS-1$
+ private static final String COMPILER_VERSION = "version"; //$NON-NLS-1$
+ public static final int EMACS = 2;
+ private static final String ERROR = "ERROR"; //$NON-NLS-1$
+ private static final String ERROR_TAG = "error"; //$NON-NLS-1$
+ private static final String EXCEPTION = "exception"; //$NON-NLS-1$
+ private static final String EXTRA_PROBLEM_TAG = "extra_problem"; //$NON-NLS-1$
+ private static final String EXTRA_PROBLEMS = "extra_problems"; //$NON-NLS-1$
+ private static final HashtableOfInt FIELD_TABLE = new HashtableOfInt();
+ private static final String KEY = "key"; //$NON-NLS-1$
+ private static final String MESSAGE = "message"; //$NON-NLS-1$
+ private static final String NUMBER_OF_CLASSFILES = "number_of_classfiles"; //$NON-NLS-1$
+ private static final String NUMBER_OF_ERRORS = "errors"; //$NON-NLS-1$
+ private static final String NUMBER_OF_LINES = "number_of_lines"; //$NON-NLS-1$
+ private static final String NUMBER_OF_PROBLEMS = "problems"; //$NON-NLS-1$
+ private static final String NUMBER_OF_TASKS = "tasks"; //$NON-NLS-1$
+ private static final String NUMBER_OF_WARNINGS = "warnings"; //$NON-NLS-1$
+ private static final String OPTION = "option"; //$NON-NLS-1$
+ private static final String OPTIONS = "options"; //$NON-NLS-1$
+ private static final String OUTPUT = "output"; //$NON-NLS-1$
+ private static final String PACKAGE = "package"; //$NON-NLS-1$
+ private static final String PATH = "path"; //$NON-NLS-1$
+ private static final String PROBLEM_ARGUMENT = "argument"; //$NON-NLS-1$
+ private static final String PROBLEM_ARGUMENT_VALUE = "value"; //$NON-NLS-1$
+ private static final String PROBLEM_ARGUMENTS = "arguments"; //$NON-NLS-1$
+ private static final String PROBLEM_CATEGORY_ID = "categoryID"; //$NON-NLS-1$
+ private static final String ID = "id"; //$NON-NLS-1$
+ private static final String PROBLEM_ID = "problemID"; //$NON-NLS-1$
+ private static final String PROBLEM_LINE = "line"; //$NON-NLS-1$
+ private static final String PROBLEM_OPTION_KEY = "optionKey"; //$NON-NLS-1$
+ private static final String PROBLEM_MESSAGE = "message"; //$NON-NLS-1$
+ private static final String PROBLEM_SEVERITY = "severity"; //$NON-NLS-1$
+ private static final String PROBLEM_SOURCE_END = "charEnd"; //$NON-NLS-1$
+ private static final String PROBLEM_SOURCE_START = "charStart"; //$NON-NLS-1$
+ private static final String PROBLEM_SUMMARY = "problem_summary"; //$NON-NLS-1$
+ private static final String PROBLEM_TAG = "problem"; //$NON-NLS-1$
+ private static final String PROBLEMS = "problems"; //$NON-NLS-1$
+ private static final String SOURCE = "source"; //$NON-NLS-1$
+ private static final String SOURCE_CONTEXT = "source_context"; //$NON-NLS-1$
+ private static final String SOURCE_END = "sourceEnd"; //$NON-NLS-1$
+ private static final String SOURCE_START = "sourceStart"; //$NON-NLS-1$
+ private static final String SOURCES = "sources"; //$NON-NLS-1$
+
+ private static final String STATS = "stats"; //$NON-NLS-1$
+
+ private static final String TASK = "task"; //$NON-NLS-1$
+ private static final String TASKS = "tasks"; //$NON-NLS-1$
+ private static final String TIME = "time"; //$NON-NLS-1$
+ private static final String VALUE = "value"; //$NON-NLS-1$
+ private static final String WARNING = "WARNING"; //$NON-NLS-1$
+ public static final int XML = 1;
+ private static final String XML_DTD_DECLARATION = "<!DOCTYPE compiler PUBLIC \"-//Eclipse.org//DTD Eclipse JDT 3.2.003 Compiler//EN\" \"http://www.eclipse.org/jdt/core/compiler_32_003.dtd\">"; //$NON-NLS-1$
+ static {
+ try {
+ Class c = IProblem.class;
+ Field[] fields = c.getFields();
+ for (int i = 0, max = fields.length; i < max; i++) {
+ Field field = fields[i];
+ if (field.getType().equals(Integer.TYPE)) {
+ Integer value = (Integer) field.get(null);
+ int key2 = value.intValue() & IProblem.IgnoreCategoriesMask;
+ if (key2 == 0) {
+ key2 = Integer.MAX_VALUE;
+ }
+ Logger.FIELD_TABLE.put(key2, field.getName());
+ }
+ }
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ }
+ public Logger(Main main, PrintWriter out, PrintWriter err) {
+ this.out = out;
+ this.err = err;
+ this.parameters = new HashMap();
+ this.main = main;
+ }
+
+//{ObjectTeams
+ /* lists of IProblem objects */
+ public ArrayList<IProblem> _globalProblems;
+ public ArrayList<IProblem> _globalErrors;
+ public ArrayList<IProblem> _globalWarnings;
+ public int _errorCode = -1;
+//carp}
+
+ public String buildFileName(
+ String outputPath,
+ String relativeFileName) {
+ char fileSeparatorChar = File.separatorChar;
+ String fileSeparator = File.separator;
+
+ outputPath = outputPath.replace('/', fileSeparatorChar);
+ // To be able to pass the mkdirs() method we need to remove the extra file separator at the end of the outDir name
+ StringBuffer outDir = new StringBuffer(outputPath);
+ if (!outputPath.endsWith(fileSeparator)) {
+ outDir.append(fileSeparator);
+ }
+ StringTokenizer tokenizer =
+ new StringTokenizer(relativeFileName, fileSeparator);
+ String token = tokenizer.nextToken();
+ while (tokenizer.hasMoreTokens()) {
+ outDir.append(token).append(fileSeparator);
+ token = tokenizer.nextToken();
+ }
+ // token contains the last one
+ return outDir.append(token).toString();
+ }
+
+ public void close() {
+ if (this.log != null) {
+ if ((this.tagBits & Logger.XML) != 0) {
+ endTag(Logger.COMPILER);
+ flush();
+ }
+ this.log.close();
+ }
+ }
+
+ /**
+ *
+ */
+ public void compiling() {
+ printlnOut(this.main.bind("progress.compiling")); //$NON-NLS-1$
+ }
+ private void endLoggingExtraProblems() {
+ endTag(Logger.EXTRA_PROBLEMS);
+ }
+ /**
+ * Used to stop logging problems.
+ * Only use in xml mode.
+ */
+ private void endLoggingProblems() {
+ endTag(Logger.PROBLEMS);
+ }
+ public void endLoggingSource() {
+ if ((this.tagBits & Logger.XML) != 0) {
+ endTag(Logger.SOURCE);
+ }
+ }
+
+ public void endLoggingSources() {
+ if ((this.tagBits & Logger.XML) != 0) {
+ endTag(Logger.SOURCES);
+ }
+ }
+
+ public void endLoggingTasks() {
+ if ((this.tagBits & Logger.XML) != 0) {
+ endTag(Logger.TASKS);
+ }
+ }
+ private void endTag(String name) {
+ if (this.log != null) {
+ ((GenericXMLWriter) this.log).endTag(name, true, true);
+ }
+ }
+ private String errorReportSource(CategorizedProblem problem, char[] unitSource, int bits) {
+ //extra from the source the innacurate token
+ //and "highlight" it using some underneath ^^^^^
+ //put some context around too.
+
+ //this code assumes that the font used in the console is fixed size
+
+ //sanity .....
+ int startPosition = problem.getSourceStart();
+ int endPosition = problem.getSourceEnd();
+ if (unitSource == null) {
+ if (problem.getOriginatingFileName() != null) {
+ try {
+ unitSource = Util.getFileCharContent(new File(new String(problem.getOriginatingFileName())), null);
+ } catch (IOException e) {
+ // ignore;
+ }
+ }
+ }
+ int length = unitSource == null ? 0 : unitSource.length;
+ if ((startPosition > endPosition)
+ || ((startPosition < 0) && (endPosition < 0))
+ || length == 0)
+ return Messages.problem_noSourceInformation;
+
+ StringBuffer errorBuffer = new StringBuffer();
+ if ((bits & Main.Logger.EMACS) == 0) {
+ errorBuffer.append(' ').append(Messages.bind(Messages.problem_atLine, String.valueOf(problem.getSourceLineNumber())));
+ errorBuffer.append(Util.LINE_SEPARATOR);
+ }
+ errorBuffer.append('\t');
+
+ char c;
+ final char SPACE = '\u0020';
+ final char MARK = '^';
+ final char TAB = '\t';
+ //the next code tries to underline the token.....
+ //it assumes (for a good display) that token source does not
+ //contain any \r \n. This is false on statements !
+ //(the code still works but the display is not optimal !)
+
+ // expand to line limits
+ int begin;
+ int end;
+ for (begin = startPosition >= length ? length - 1 : startPosition; begin > 0; begin--) {
+ if ((c = unitSource[begin - 1]) == '\n' || c == '\r') break;
+ }
+ for (end = endPosition >= length ? length - 1 : endPosition ; end+1 < length; end++) {
+ if ((c = unitSource[end + 1]) == '\r' || c == '\n') break;
+ }
+
+ // trim left and right spaces/tabs
+ while ((c = unitSource[begin]) == ' ' || c == '\t') begin++;
+ //while ((c = unitSource[end]) == ' ' || c == '\t') end--; TODO (philippe) should also trim right, but all tests are to be updated
+
+ // copy source
+ errorBuffer.append(unitSource, begin, end-begin+1);
+ errorBuffer.append(Util.LINE_SEPARATOR).append("\t"); //$NON-NLS-1$
+
+ // compute underline
+ for (int i = begin; i <startPosition; i++) {
+ errorBuffer.append((unitSource[i] == TAB) ? TAB : SPACE);
+ }
+ for (int i = startPosition; i <= (endPosition >= length ? length - 1 : endPosition); i++) {
+ errorBuffer.append(MARK);
+ }
+ return errorBuffer.toString();
+ }
+
+ private void extractContext(CategorizedProblem problem, char[] unitSource) {
+ //sanity .....
+ int startPosition = problem.getSourceStart();
+ int endPosition = problem.getSourceEnd();
+ if (unitSource == null) {
+ if (problem.getOriginatingFileName() != null) {
+ try {
+ unitSource = Util.getFileCharContent(new File(new String(problem.getOriginatingFileName())), null);
+ } catch(IOException e) {
+ // ignore
+ }
+ }
+ }
+ int length = unitSource== null ? 0 : unitSource.length;
+ if ((startPosition > endPosition)
+ || ((startPosition < 0) && (endPosition < 0))
+ || (length <= 0)
+ || (endPosition > length)) {
+ this.parameters.put(Logger.VALUE, Messages.problem_noSourceInformation);
+ this.parameters.put(Logger.SOURCE_START, "-1"); //$NON-NLS-1$
+ this.parameters.put(Logger.SOURCE_END, "-1"); //$NON-NLS-1$
+ printTag(Logger.SOURCE_CONTEXT, this.parameters, true, true);
+ return;
+ }
+
+ char c;
+ //the next code tries to underline the token.....
+ //it assumes (for a good display) that token source does not
+ //contain any \r \n. This is false on statements !
+ //(the code still works but the display is not optimal !)
+
+ // expand to line limits
+ int begin, end;
+ for (begin = startPosition >= length ? length - 1 : startPosition; begin > 0; begin--) {
+ if ((c = unitSource[begin - 1]) == '\n' || c == '\r') break;
+ }
+ for (end = endPosition >= length ? length - 1 : endPosition ; end+1 < length; end++) {
+ if ((c = unitSource[end + 1]) == '\r' || c == '\n') break;
+ }
+
+ // trim left and right spaces/tabs
+ while ((c = unitSource[begin]) == ' ' || c == '\t') begin++;
+ while ((c = unitSource[end]) == ' ' || c == '\t') end--;
+
+ // copy source
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(unitSource, begin, end - begin + 1);
+
+ this.parameters.put(Logger.VALUE, String.valueOf(buffer));
+ this.parameters.put(Logger.SOURCE_START, Integer.toString(startPosition - begin));
+ this.parameters.put(Logger.SOURCE_END, Integer.toString(endPosition - begin));
+ printTag(Logger.SOURCE_CONTEXT, this.parameters, true, true);
+ }
+ public void flush() {
+ this.out.flush();
+ this.err.flush();
+ if (this.log != null) {
+ this.log.flush();
+ }
+ }
+
+ private String getFieldName(int id) {
+ int key2 = id & IProblem.IgnoreCategoriesMask;
+ if (key2 == 0) {
+ key2 = Integer.MAX_VALUE;
+ }
+ return (String) Logger.FIELD_TABLE.get(key2);
+ }
+
+ // find out an option name controlling a given problemID
+ private String getProblemOptionKey(int problemID) {
+ int irritant = ProblemReporter.getIrritant(problemID);
+ return CompilerOptions.optionKeyFromIrritant(irritant);
+ }
+
+ public void logAverage() {
+ Arrays.sort(this.main.compilerStats);
+ long lineCount = this.main.compilerStats[0].lineCount;
+ final int length = this.main.maxRepetition;
+ long sum = 0;
+ long parseSum = 0, resolveSum = 0, analyzeSum = 0, generateSum = 0;
+ for (int i = 1, max = length - 1; i < max; i++) {
+ CompilerStats stats = this.main.compilerStats[i];
+ sum += stats.elapsedTime();
+ parseSum += stats.parseTime;
+ resolveSum += stats.resolveTime;
+ analyzeSum += stats.analyzeTime;
+ generateSum += stats.generateTime;
+ }
+ long time = sum / (length - 2);
+ long parseTime = parseSum/(length - 2);
+ long resolveTime = resolveSum/(length - 2);
+ long analyzeTime = analyzeSum/(length - 2);
+ long generateTime = generateSum/(length - 2);
+ printlnOut(this.main.bind(
+ "compile.averageTime", //$NON-NLS-1$
+ new String[] {
+ String.valueOf(lineCount),
+ String.valueOf(time),
+ String.valueOf(((int) (lineCount * 10000.0 / time)) / 10.0),
+ }));
+ if ((this.main.timing & Main.TIMING_DETAILED) != 0) {
+ printlnOut(
+ this.main.bind("compile.detailedTime", //$NON-NLS-1$
+ new String[] {
+ String.valueOf(parseTime),
+ String.valueOf(((int) (parseTime * 1000.0 / time)) / 10.0),
+ String.valueOf(resolveTime),
+ String.valueOf(((int) (resolveTime * 1000.0 / time)) / 10.0),
+ String.valueOf(analyzeTime),
+ String.valueOf(((int) (analyzeTime * 1000.0 / time)) / 10.0),
+ String.valueOf(generateTime),
+ String.valueOf(((int) (generateTime * 1000.0 / time)) / 10.0),
+ }));
+ }
+ }
+ public void logClassFile(boolean generatePackagesStructure, String outputPath, String relativeFileName) {
+ if ((this.tagBits & Logger.XML) != 0) {
+ String fileName = null;
+ if (generatePackagesStructure) {
+ fileName = buildFileName(outputPath, relativeFileName);
+ } else {
+ char fileSeparatorChar = File.separatorChar;
+ String fileSeparator = File.separator;
+ // First we ensure that the outputPath exists
+ outputPath = outputPath.replace('/', fileSeparatorChar);
+ // To be able to pass the mkdirs() method we need to remove the extra file separator at the end of the outDir name
+ int indexOfPackageSeparator = relativeFileName.lastIndexOf(fileSeparatorChar);
+ if (indexOfPackageSeparator == -1) {
+ if (outputPath.endsWith(fileSeparator)) {
+ fileName = outputPath + relativeFileName;
+ } else {
+ fileName = outputPath + fileSeparator + relativeFileName;
+ }
+ } else {
+ int length = relativeFileName.length();
+ if (outputPath.endsWith(fileSeparator)) {
+ fileName = outputPath + relativeFileName.substring(indexOfPackageSeparator + 1, length);
+ } else {
+ fileName = outputPath + fileSeparator + relativeFileName.substring(indexOfPackageSeparator + 1, length);
+ }
+ }
+ }
+ File f = new File(fileName);
+ try {
+ this.parameters.put(Logger.PATH, f.getCanonicalPath());
+ printTag(Logger.CLASS_FILE, this.parameters, true, true);
+ } catch (IOException e) {
+ logNoClassFileCreated(outputPath, relativeFileName, e);
+ }
+ }
+ }
+ public void logClasspath(FileSystem.Classpath[] classpaths) {
+ if (classpaths == null) return;
+ if ((this.tagBits & Logger.XML) != 0) {
+ final int length = classpaths.length;
+ if (length != 0) {
+ // generate xml output
+ printTag(Logger.CLASSPATHS, null, true, false);
+ for (int i = 0; i < length; i++) {
+ String classpath = classpaths[i].getPath();
+ this.parameters.put(Logger.PATH, classpath);
+ File f = new File(classpath);
+ String id = null;
+ if (f.isFile()) {
+ if (Util.isPotentialZipArchive(classpath)) {
+ id = Logger.CLASSPATH_JAR;
+ } else {
+ id = Logger.CLASSPATH_FILE;
+ }
+ } else if (f.isDirectory()) {
+ id = Logger.CLASSPATH_FOLDER;
+ }
+ if (id != null) {
+ this.parameters.put(Logger.CLASSPATH_ID, id);
+ printTag(Logger.CLASSPATH, this.parameters, true, true);
+ }
+ }
+ endTag(Logger.CLASSPATHS);
+ }
+ }
+
+ }
+
+ public void logCommandLineArguments(String[] commandLineArguments) {
+ if (commandLineArguments == null) return;
+ if ((this.tagBits & Logger.XML) != 0) {
+ final int length = commandLineArguments.length;
+ if (length != 0) {
+ // generate xml output
+ printTag(Logger.COMMAND_LINE_ARGUMENTS, null, true, false);
+ for (int i = 0; i < length; i++) {
+ this.parameters.put(Logger.VALUE, commandLineArguments[i]);
+ printTag(Logger.COMMAND_LINE_ARGUMENT, this.parameters, true, true);
+ }
+ endTag(Logger.COMMAND_LINE_ARGUMENTS);
+ }
+ }
+ }
+
+ /**
+ * @param e the given exception to log
+ */
+ public void logException(Exception e) {
+ StringWriter writer = new StringWriter();
+ PrintWriter printWriter = new PrintWriter(writer);
+ e.printStackTrace(printWriter);
+ printWriter.flush();
+ printWriter.close();
+ final String stackTrace = writer.toString();
+ if ((this.tagBits & Logger.XML) != 0) {
+ LineNumberReader reader = new LineNumberReader(new StringReader(stackTrace));
+ String line;
+ int i = 0;
+ StringBuffer buffer = new StringBuffer();
+ String message = e.getMessage();
+ if (message != null) {
+ buffer.append(message).append(Util.LINE_SEPARATOR);
+ }
+ try {
+ while ((line = reader.readLine()) != null && i < 4) {
+ buffer.append(line).append(Util.LINE_SEPARATOR);
+ i++;
+ }
+ reader.close();
+ } catch (IOException e1) {
+ // ignore
+ }
+ message = buffer.toString();
+ this.parameters.put(Logger.MESSAGE, message);
+ this.parameters.put(Logger.CLASS, e.getClass());
+ printTag(Logger.EXCEPTION, this.parameters, true, true);
+ }
+ String message = e.getMessage();
+ if (message == null) {
+ this.printlnErr(stackTrace);
+ } else {
+ this.printlnErr(message);
+ }
+ }
+
+ private void logExtraProblem(CategorizedProblem problem, int localErrorCount, int globalErrorCount) {
+ char[] originatingFileName = problem.getOriginatingFileName();
+ String fileName =
+ originatingFileName == null
+ ? this.main.bind("requestor.noFileNameSpecified")//$NON-NLS-1$
+ : new String(originatingFileName);
+ if ((this.tagBits & Logger.EMACS) != 0) {
+ String result = fileName
+ + ":" //$NON-NLS-1$
+ + problem.getSourceLineNumber()
+ + ": " //$NON-NLS-1$
+ + (problem.isError() ? this.main.bind("output.emacs.error") : this.main.bind("output.emacs.warning")) //$NON-NLS-1$ //$NON-NLS-2$
+ + ": " //$NON-NLS-1$
+ + problem.getMessage();
+ this.printlnErr(result);
+ final String errorReportSource = errorReportSource(problem, null, this.tagBits);
+ this.printlnErr(errorReportSource);
+ } else {
+ if (localErrorCount == 0) {
+ this.printlnErr("----------"); //$NON-NLS-1$
+ }
+ printErr(problem.isError() ?
+ this.main.bind(
+ "requestor.error", //$NON-NLS-1$
+ Integer.toString(globalErrorCount),
+ new String(fileName))
+ : this.main.bind(
+ "requestor.warning", //$NON-NLS-1$
+ Integer.toString(globalErrorCount),
+ new String(fileName)));
+ final String errorReportSource = errorReportSource(problem, null, 0);
+ this.printlnErr(errorReportSource);
+ this.printlnErr(problem.getMessage());
+ this.printlnErr("----------"); //$NON-NLS-1$
+ }
+ }
+
+ public void loggingExtraProblems(Main currentMain) {
+ ArrayList problems = currentMain.extraProblems;
+ final int count = problems.size();
+ int localErrorCount = 0;
+ int localProblemCount = 0;
+ if (count != 0) {
+ int errors = 0;
+ int warnings = 0;
+ for (int i = 0; i < count; i++) {
+ CategorizedProblem problem = (CategorizedProblem) problems.get(i);
+ if (problem != null) {
+ currentMain.globalProblemsCount++;
+ logExtraProblem(problem, localProblemCount, currentMain.globalProblemsCount);
+ localProblemCount++;
+ if (problem.isError()) {
+ localErrorCount++;
+ errors++;
+ currentMain.globalErrorsCount++;
+ } else if (problem.isWarning()) {
+ currentMain.globalWarningsCount++;
+ warnings++;
+ }
+ }
+ }
+ if ((this.tagBits & Logger.XML) != 0) {
+ if ((errors + warnings) != 0) {
+ startLoggingExtraProblems(count);
+ for (int i = 0; i < count; i++) {
+ CategorizedProblem problem = (CategorizedProblem) problems.get(i);
+ if (problem!= null) {
+ if (problem.getID() != IProblem.Task) {
+ logXmlExtraProblem(problem, localProblemCount, currentMain.globalProblemsCount);
+ }
+ }
+ }
+ endLoggingExtraProblems();
+ }
+ }
+ }
+ }
+
+ public void logIncorrectVMVersionForAnnotationProcessing() {
+ if ((this.tagBits & Logger.XML) != 0) {
+ this.parameters.put(Logger.MESSAGE, this.main.bind("configure.incorrectVMVersionforAPT")); //$NON-NLS-1$
+ printTag(Logger.ERROR_TAG, this.parameters, true, true);
+ }
+ this.printlnErr(this.main.bind("configure.incorrectVMVersionforAPT")); //$NON-NLS-1$
+ }
+
+ /**
+ *
+ */
+ public void logNoClassFileCreated(String outputDir, String relativeFileName, IOException e) {
+ if ((this.tagBits & Logger.XML) != 0) {
+ this.parameters.put(Logger.MESSAGE, this.main.bind("output.noClassFileCreated", //$NON-NLS-1$
+ new String[] {
+ outputDir,
+ relativeFileName,
+ e.getMessage()
+ }));
+ printTag(Logger.ERROR_TAG, this.parameters, true, true);
+ }
+ this.printlnErr(this.main.bind("output.noClassFileCreated", //$NON-NLS-1$
+ new String[] {
+ outputDir,
+ relativeFileName,
+ e.getMessage()
+ }));
+ }
+
+ /**
+ * @param exportedClassFilesCounter
+ */
+ public void logNumberOfClassFilesGenerated(int exportedClassFilesCounter) {
+ if ((this.tagBits & Logger.XML) != 0) {
+ this.parameters.put(Logger.VALUE, new Integer(exportedClassFilesCounter));
+ printTag(Logger.NUMBER_OF_CLASSFILES, this.parameters, true, true);
+ }
+ if (exportedClassFilesCounter == 1) {
+ printlnOut(this.main.bind("compile.oneClassFileGenerated")); //$NON-NLS-1$
+ } else {
+ printlnOut(this.main.bind("compile.severalClassFilesGenerated", //$NON-NLS-1$
+ String.valueOf(exportedClassFilesCounter)));
+ }
+ }
+
+ /**
+ * @param options the given compiler options
+ */
+ public void logOptions(Map options) {
+ if ((this.tagBits & Logger.XML) != 0) {
+ printTag(Logger.OPTIONS, null, true, false);
+ final Set entriesSet = options.entrySet();
+ Object[] entries = entriesSet.toArray();
+ Arrays.sort(entries, new Comparator() {
+ public int compare(Object o1, Object o2) {
+ Map.Entry entry1 = (Map.Entry) o1;
+ Map.Entry entry2 = (Map.Entry) o2;
+ return ((String) entry1.getKey()).compareTo((String) entry2.getKey());
+ }
+ });
+ for (int i = 0, max = entries.length; i < max; i++) {
+ Map.Entry entry = (Map.Entry) entries[i];
+ String key = (String) entry.getKey();
+ this.parameters.put(Logger.KEY, key);
+ this.parameters.put(Logger.VALUE, entry.getValue());
+ printTag(Logger.OPTION, this.parameters, true, true);
+ }
+ endTag(Logger.OPTIONS);
+ }
+ }
+
+ /**
+ * @param error the given error
+ */
+ public void logPendingError(String error) {
+ if ((this.tagBits & Logger.XML) != 0) {
+ this.parameters.put(Logger.MESSAGE, error);
+ printTag(Logger.ERROR_TAG, this.parameters, true, true);
+ }
+ this.printlnErr(error);
+ }
+
+ private void logProblem(CategorizedProblem problem, int localErrorCount,
+ int globalErrorCount, char[] unitSource) {
+ if ((this.tagBits & Logger.EMACS) != 0) {
+ String result = (new String(problem.getOriginatingFileName())
+ + ":" //$NON-NLS-1$
+ + problem.getSourceLineNumber()
+ + ": " //$NON-NLS-1$
+ + (problem.isError() ? this.main.bind("output.emacs.error") : this.main.bind("output.emacs.warning")) //$NON-NLS-1$ //$NON-NLS-2$
+ + ": " //$NON-NLS-1$
+ + problem.getMessage());
+ this.printlnErr(result);
+ final String errorReportSource = errorReportSource(problem, unitSource, this.tagBits);
+ if (errorReportSource.length() != 0) this.printlnErr(errorReportSource);
+ } else {
+ if (localErrorCount == 0) {
+ this.printlnErr("----------"); //$NON-NLS-1$
+ }
+ printErr(problem.isError() ?
+ this.main.bind(
+ "requestor.error", //$NON-NLS-1$
+ Integer.toString(globalErrorCount),
+ new String(problem.getOriginatingFileName()))
+ : this.main.bind(
+ "requestor.warning", //$NON-NLS-1$
+ Integer.toString(globalErrorCount),
+ new String(problem.getOriginatingFileName())));
+ try {
+ final String errorReportSource = errorReportSource(problem, unitSource, 0);
+ this.printlnErr(errorReportSource);
+ this.printlnErr(problem.getMessage());
+ } catch (Exception e) {
+ this.printlnErr(this.main.bind(
+ "requestor.notRetrieveErrorMessage", problem.toString())); //$NON-NLS-1$
+ }
+ this.printlnErr("----------"); //$NON-NLS-1$
+ }
+//{ObjectTeams
+ _globalProblems.add(problem);
+ if (problem.isError()) {
+ // make exceptions distinguishable:
+ _globalErrors.add(problem);
+ if (problem.getID() == IProblem.Unclassified)
+ _errorCode = -2; // signal an exception occurred.
+ } else if (problem.isWarning()) {
+ _globalWarnings.add(problem);
+ }
+//carp+SH}
+ }
+
+ public int logProblems(CategorizedProblem[] problems, char[] unitSource, Main currentMain) {
+ final int count = problems.length;
+ int localErrorCount = 0;
+ int localProblemCount = 0;
+ if (count != 0) {
+ int errors = 0;
+ int warnings = 0;
+ int tasks = 0;
+ for (int i = 0; i < count; i++) {
+ CategorizedProblem problem = problems[i];
+ if (problem != null) {
+ currentMain.globalProblemsCount++;
+ logProblem(problem, localProblemCount, currentMain.globalProblemsCount, unitSource);
+ localProblemCount++;
+ if (problem.isError()) {
+ localErrorCount++;
+ errors++;
+ currentMain.globalErrorsCount++;
+ } else if (problem.getID() == IProblem.Task) {
+ currentMain.globalTasksCount++;
+ tasks++;
+ } else {
+ currentMain.globalWarningsCount++;
+ warnings++;
+ }
+ }
+ }
+ if ((this.tagBits & Logger.XML) != 0) {
+ if ((errors + warnings) != 0) {
+ startLoggingProblems(errors, warnings);
+ for (int i = 0; i < count; i++) {
+ CategorizedProblem problem = problems[i];
+ if (problem!= null) {
+ if (problem.getID() != IProblem.Task) {
+ logXmlProblem(problem, unitSource);
+ }
+ }
+ }
+ endLoggingProblems();
+ }
+ if (tasks != 0) {
+ startLoggingTasks(tasks);
+ for (int i = 0; i < count; i++) {
+ CategorizedProblem problem = problems[i];
+ if (problem!= null) {
+ if (problem.getID() == IProblem.Task) {
+ logXmlTask(problem, unitSource);
+ }
+ }
+ }
+ endLoggingTasks();
+ }
+ }
+ }
+ return localErrorCount;
+ }
+
+ /**
+ * @param globalProblemsCount
+ * @param globalErrorsCount
+ * @param globalWarningsCount
+ */
+ public void logProblemsSummary(int globalProblemsCount,
+ int globalErrorsCount, int globalWarningsCount, int globalTasksCount) {
+ if ((this.tagBits & Logger.XML) != 0) {
+ // generate xml
+ this.parameters.put(Logger.NUMBER_OF_PROBLEMS, new Integer(globalProblemsCount));
+ this.parameters.put(Logger.NUMBER_OF_ERRORS, new Integer(globalErrorsCount));
+ this.parameters.put(Logger.NUMBER_OF_WARNINGS, new Integer(globalWarningsCount));
+ this.parameters.put(Logger.NUMBER_OF_TASKS, new Integer(globalTasksCount));
+ printTag(Logger.PROBLEM_SUMMARY, this.parameters, true, true);
+ }
+ if (globalProblemsCount == 1) {
+ String message = null;
+ if (globalErrorsCount == 1) {
+ message = this.main.bind("compile.oneError"); //$NON-NLS-1$
+ } else {
+ message = this.main.bind("compile.oneWarning"); //$NON-NLS-1$
+ }
+ printErr(this.main.bind("compile.oneProblem", message)); //$NON-NLS-1$
+ } else {
+ String errorMessage = null;
+ String warningMessage = null;
+ if (globalErrorsCount > 0) {
+ if (globalErrorsCount == 1) {
+ errorMessage = this.main.bind("compile.oneError"); //$NON-NLS-1$
+ } else {
+ errorMessage = this.main.bind("compile.severalErrors", String.valueOf(globalErrorsCount)); //$NON-NLS-1$
+ }
+ }
+ int warningsNumber = globalWarningsCount + globalTasksCount;
+ if (warningsNumber > 0) {
+ if (warningsNumber == 1) {
+ warningMessage = this.main.bind("compile.oneWarning"); //$NON-NLS-1$
+ } else {
+ warningMessage = this.main.bind("compile.severalWarnings", String.valueOf(warningsNumber)); //$NON-NLS-1$
+ }
+ }
+ if (errorMessage == null || warningMessage == null) {
+ if (errorMessage == null) {
+ printErr(this.main.bind(
+ "compile.severalProblemsErrorsOrWarnings", //$NON-NLS-1$
+ String.valueOf(globalProblemsCount),
+ warningMessage));
+ } else {
+ printErr(this.main.bind(
+ "compile.severalProblemsErrorsOrWarnings", //$NON-NLS-1$
+ String.valueOf(globalProblemsCount),
+ errorMessage));
+ }
+ } else {
+ printErr(this.main.bind(
+ "compile.severalProblemsErrorsAndWarnings", //$NON-NLS-1$
+ new String[] {
+ String.valueOf(globalProblemsCount),
+ errorMessage,
+ warningMessage
+ }));
+ }
+ }
+ if ((this.tagBits & Logger.EMACS) != 0) {
+ this.printlnErr();
+ }
+ }
+
+ /**
+ *
+ */
+ public void logProgress() {
+ printOut('.');
+ }
+
+ /**
+ * @param i
+ * the current repetition number
+ * @param repetitions
+ * the given number of repetitions
+ */
+ public void logRepetition(int i, int repetitions) {
+ printlnOut(this.main.bind("compile.repetition", //$NON-NLS-1$
+ String.valueOf(i + 1), String.valueOf(repetitions)));
+ }
+ /**
+ * @param compilerStats
+ */
+ public void logTiming(CompilerStats compilerStats) {
+ long time = compilerStats.elapsedTime();
+ long lineCount = compilerStats.lineCount;
+ if ((this.tagBits & Logger.XML) != 0) {
+ this.parameters.put(Logger.VALUE, new Long(time));
+ printTag(Logger.TIME, this.parameters, true, true);
+ this.parameters.put(Logger.VALUE, new Long(lineCount));
+ printTag(Logger.NUMBER_OF_LINES, this.parameters, true, true);
+ }
+ if (lineCount != 0) {
+ printlnOut(
+ this.main.bind("compile.instantTime", //$NON-NLS-1$
+ new String[] {
+ String.valueOf(lineCount),
+ String.valueOf(time),
+ String.valueOf(((int) (lineCount * 10000.0 / time)) / 10.0),
+ }));
+ } else {
+ printlnOut(
+ this.main.bind("compile.totalTime", //$NON-NLS-1$
+ new String[] {
+ String.valueOf(time),
+ }));
+ }
+ if ((this.main.timing & Main.TIMING_DETAILED) != 0) {
+ printlnOut(
+ this.main.bind("compile.detailedTime", //$NON-NLS-1$
+ new String[] {
+ String.valueOf(compilerStats.parseTime),
+ String.valueOf(((int) (compilerStats.parseTime * 1000.0 / time)) / 10.0),
+ String.valueOf(compilerStats.resolveTime),
+ String.valueOf(((int) (compilerStats.resolveTime * 1000.0 / time)) / 10.0),
+ String.valueOf(compilerStats.analyzeTime),
+ String.valueOf(((int) (compilerStats.analyzeTime * 1000.0 / time)) / 10.0),
+ String.valueOf(compilerStats.generateTime),
+ String.valueOf(((int) (compilerStats.generateTime * 1000.0 / time)) / 10.0),
+ }));
+ }
+ }
+
+ /**
+ * Print the usage of the compiler
+ * @param usage
+ */
+ public void logUsage(String usage) {
+ printlnOut(usage);
+ }
+
+ /**
+ * Print the version of the compiler in the log and/or the out field
+ */
+ public void logVersion(final boolean printToOut) {
+ if (this.log != null && (this.tagBits & Logger.XML) == 0) {
+ final String version = this.main.bind("misc.version", //$NON-NLS-1$
+ new String[] {
+ this.main.bind("compiler.name"), //$NON-NLS-1$
+ this.main.bind("compiler.version"), //$NON-NLS-1$
+ this.main.bind("compiler.copyright") //$NON-NLS-1$
+//{ObjectTeams: more version info
+ ,
+ this.main.bind("otdtc.name"), //$NON-NLS-1$
+ this.main.bind("otdtc.version"), //$NON-NLS-1$
+ this.main.bind("otdtc.copyright") //$NON-NLS-1$
+// SH}
+
+ }
+ );
+ this.log.println("# " + version); //$NON-NLS-1$
+ if (printToOut) {
+ this.out.println(version);
+ this.out.flush();
+ }
+ } else if (printToOut) {
+ final String version = this.main.bind("misc.version", //$NON-NLS-1$
+ new String[] {
+ this.main.bind("compiler.name"), //$NON-NLS-1$
+ this.main.bind("compiler.version"), //$NON-NLS-1$
+ this.main.bind("compiler.copyright") //$NON-NLS-1$
+//{ObjectTeams: more version info
+ ,
+ this.main.bind("otdtc.name"), //$NON-NLS-1$
+ this.main.bind("otdtc.version"), //$NON-NLS-1$
+ this.main.bind("otdtc.copyright") //$NON-NLS-1$
+// SH}
+
+ }
+ );
+ this.out.println(version);
+ this.out.flush();
+ }
+ }
+
+ /**
+ * Print the usage of wrong JDK
+ */
+ public void logWrongJDK() {
+ if ((this.tagBits & Logger.XML) != 0) {
+ this.parameters.put(Logger.MESSAGE, this.main.bind("configure.requiresJDK1.2orAbove")); //$NON-NLS-1$
+ printTag(Logger.ERROR, this.parameters, true, true);
+ }
+ this.printlnErr(this.main.bind("configure.requiresJDK1.2orAbove")); //$NON-NLS-1$
+ }
+
+ private void logXmlExtraProblem(CategorizedProblem problem, int globalErrorCount, int localErrorCount) {
+ final int sourceStart = problem.getSourceStart();
+ final int sourceEnd = problem.getSourceEnd();
+ boolean isError = problem.isError();
+ this.parameters.put(Logger.PROBLEM_SEVERITY, isError ? Logger.ERROR : Logger.WARNING);
+ this.parameters.put(Logger.PROBLEM_LINE, new Integer(problem.getSourceLineNumber()));
+ this.parameters.put(Logger.PROBLEM_SOURCE_START, new Integer(sourceStart));
+ this.parameters.put(Logger.PROBLEM_SOURCE_END, new Integer(sourceEnd));
+ printTag(Logger.EXTRA_PROBLEM_TAG, this.parameters, true, false);
+ this.parameters.put(Logger.VALUE, problem.getMessage());
+ printTag(Logger.PROBLEM_MESSAGE, this.parameters, true, true);
+ extractContext(problem, null);
+ endTag(Logger.EXTRA_PROBLEM_TAG);
+ }
+ /**
+ * @param problem
+ * the given problem to log
+ * @param unitSource
+ * the given unit source
+ */
+ private void logXmlProblem(CategorizedProblem problem, char[] unitSource) {
+ final int sourceStart = problem.getSourceStart();
+ final int sourceEnd = problem.getSourceEnd();
+ final int id = problem.getID();
+ this.parameters.put(Logger.ID, getFieldName(id)); // ID as field name
+ this.parameters.put(Logger.PROBLEM_ID, new Integer(id)); // ID as numeric value
+ boolean isError = problem.isError();
+ int severity = isError ? ProblemSeverities.Error : ProblemSeverities.Warning;
+ this.parameters.put(Logger.PROBLEM_SEVERITY, isError ? Logger.ERROR : Logger.WARNING);
+ this.parameters.put(Logger.PROBLEM_LINE, new Integer(problem.getSourceLineNumber()));
+ this.parameters.put(Logger.PROBLEM_SOURCE_START, new Integer(sourceStart));
+ this.parameters.put(Logger.PROBLEM_SOURCE_END, new Integer(sourceEnd));
+ String problemOptionKey = getProblemOptionKey(id);
+ if (problemOptionKey != null) {
+ this.parameters.put(Logger.PROBLEM_OPTION_KEY, problemOptionKey);
+ }
+ int categoryID = ProblemReporter.getProblemCategory(severity, id);
+ this.parameters.put(Logger.PROBLEM_CATEGORY_ID, new Integer(categoryID));
+ printTag(Logger.PROBLEM_TAG, this.parameters, true, false);
+ this.parameters.put(Logger.VALUE, problem.getMessage());
+ printTag(Logger.PROBLEM_MESSAGE, this.parameters, true, true);
+ extractContext(problem, unitSource);
+ String[] arguments = problem.getArguments();
+ final int length = arguments.length;
+ if (length != 0) {
+ printTag(Logger.PROBLEM_ARGUMENTS, null, true, false);
+ for (int i = 0; i < length; i++) {
+ this.parameters.put(Logger.PROBLEM_ARGUMENT_VALUE, arguments[i]);
+ printTag(Logger.PROBLEM_ARGUMENT, this.parameters, true, true);
+ }
+ endTag(Logger.PROBLEM_ARGUMENTS);
+ }
+ endTag(Logger.PROBLEM_TAG);
+ }
+ /**
+ * @param problem
+ * the given problem to log
+ * @param unitSource
+ * the given unit source
+ */
+ private void logXmlTask(CategorizedProblem problem, char[] unitSource) {
+ this.parameters.put(Logger.PROBLEM_LINE, new Integer(problem.getSourceLineNumber()));
+ this.parameters.put(Logger.PROBLEM_SOURCE_START, new Integer(problem.getSourceStart()));
+ this.parameters.put(Logger.PROBLEM_SOURCE_END, new Integer(problem.getSourceEnd()));
+ String problemOptionKey = getProblemOptionKey(problem.getID());
+ if (problemOptionKey != null) {
+ this.parameters.put(Logger.PROBLEM_OPTION_KEY, problemOptionKey);
+ }
+ printTag(Logger.TASK, this.parameters, true, false);
+ this.parameters.put(Logger.VALUE, problem.getMessage());
+ printTag(Logger.PROBLEM_MESSAGE, this.parameters, true, true);
+ extractContext(problem, unitSource);
+ endTag(Logger.TASK);
+ }
+
+ private void printErr(String s) {
+ this.err.print(s);
+ if ((this.tagBits & Logger.XML) == 0 && this.log != null) {
+ this.log.print(s);
+ }
+ }
+
+ private void printlnErr() {
+ this.err.println();
+ if ((this.tagBits & Logger.XML) == 0 && this.log != null) {
+ this.log.println();
+ }
+ }
+
+ private void printlnErr(String s) {
+ this.err.println(s);
+ if ((this.tagBits & Logger.XML) == 0 && this.log != null) {
+ this.log.println(s);
+ }
+ }
+
+ private void printlnOut(String s) {
+ this.out.println(s);
+ if ((this.tagBits & Logger.XML) == 0 && this.log != null) {
+ this.log.println(s);
+ }
+ }
+
+ /**
+ *
+ */
+ public void printNewLine() {
+ this.out.println();
+ }
+
+ private void printOut(char c) {
+ this.out.print(c);
+ }
+
+ public void printStats() {
+ final boolean isTimed = (this.main.timing & TIMING_ENABLED) != 0;
+ if ((this.tagBits & Logger.XML) != 0) {
+ printTag(Logger.STATS, null, true, false);
+ }
+ if (isTimed) {
+ CompilerStats compilerStats = this.main.batchCompiler.stats;
+ compilerStats.startTime = this.main.startTime; // also include batch initialization times
+ compilerStats.endTime = System.currentTimeMillis(); // also include batch output times
+ logTiming(compilerStats);
+ }
+ if (this.main.globalProblemsCount > 0) {
+ logProblemsSummary(this.main.globalProblemsCount, this.main.globalErrorsCount, this.main.globalWarningsCount, this.main.globalTasksCount);
+ }
+ if (this.main.exportedClassFilesCounter != 0
+ && (this.main.showProgress || isTimed || this.main.verbose)) {
+ logNumberOfClassFilesGenerated(this.main.exportedClassFilesCounter);
+ }
+ if ((this.tagBits & Logger.XML) != 0) {
+ endTag(Logger.STATS);
+ }
+ }
+
+ private void printTag(String name, HashMap params, boolean insertNewLine, boolean closeTag) {
+ if (this.log != null) {
+ ((GenericXMLWriter) this.log).printTag(name, this.parameters, true, insertNewLine, closeTag);
+ }
+ this.parameters.clear();
+ }
+
+ public void setEmacs() {
+ this.tagBits |= Logger.EMACS;
+ }
+ public void setLog(String logFileName) {
+ final Date date = new Date();
+ final DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.LONG, Locale.getDefault());
+ try {
+ int index = logFileName.lastIndexOf('.');
+ if (index != -1) {
+ if (logFileName.substring(index).toLowerCase().equals(".xml")) { //$NON-NLS-1$
+ this.log = new GenericXMLWriter(new OutputStreamWriter(new FileOutputStream(logFileName, false), Util.UTF_8), Util.LINE_SEPARATOR, true);
+ this.tagBits |= Logger.XML;
+ // insert time stamp as comment
+ this.log.println("<!-- " + dateFormat.format(date) + " -->");//$NON-NLS-1$//$NON-NLS-2$
+ this.log.println(Logger.XML_DTD_DECLARATION);
+ this.parameters.put(Logger.COMPILER_NAME, this.main.bind("compiler.name")); //$NON-NLS-1$
+ this.parameters.put(Logger.COMPILER_VERSION, this.main.bind("compiler.version")); //$NON-NLS-1$
+ this.parameters.put(Logger.COMPILER_COPYRIGHT, this.main.bind("compiler.copyright")); //$NON-NLS-1$
+ printTag(Logger.COMPILER, this.parameters, true, false);
+ } else {
+ this.log = new PrintWriter(new FileOutputStream(logFileName, false));
+ this.log.println("# " + dateFormat.format(date));//$NON-NLS-1$
+ }
+ } else {
+ this.log = new PrintWriter(new FileOutputStream(logFileName, false));
+ this.log.println("# " + dateFormat.format(date));//$NON-NLS-1$
+ }
+ } catch (FileNotFoundException e) {
+ throw new IllegalArgumentException(this.main.bind("configure.cannotOpenLog", logFileName)); //$NON-NLS-1$
+ } catch (UnsupportedEncodingException e) {
+ throw new IllegalArgumentException(this.main.bind("configure.cannotOpenLogInvalidEncoding", logFileName)); //$NON-NLS-1$
+ }
+ }
+ private void startLoggingExtraProblems(int count) {
+ this.parameters.put(Logger.NUMBER_OF_PROBLEMS, new Integer(count));
+ printTag(Logger.EXTRA_PROBLEMS, this.parameters, true, false);
+ }
+
+ /**
+ * Used to start logging problems.
+ * Only use in xml mode.
+ */
+ private void startLoggingProblems(int errors, int warnings) {
+ this.parameters.put(Logger.NUMBER_OF_PROBLEMS, new Integer(errors + warnings));
+ this.parameters.put(Logger.NUMBER_OF_ERRORS, new Integer(errors));
+ this.parameters.put(Logger.NUMBER_OF_WARNINGS, new Integer(warnings));
+ printTag(Logger.PROBLEMS, this.parameters, true, false);
+ }
+
+ public void startLoggingSource(CompilationResult compilationResult) {
+ if ((this.tagBits & Logger.XML) != 0) {
+ ICompilationUnit compilationUnit = compilationResult.compilationUnit;
+ if (compilationUnit != null) {
+ char[] fileName = compilationUnit.getFileName();
+ File f = new File(new String(fileName));
+ if (fileName != null) {
+ this.parameters.put(Logger.PATH, f.getAbsolutePath());
+ }
+ char[][] packageName = compilationResult.packageName;
+ if (packageName != null) {
+ this.parameters.put(
+ Logger.PACKAGE,
+ new String(CharOperation.concatWith(packageName, File.separatorChar)));
+ }
+ CompilationUnit unit = (CompilationUnit) compilationUnit;
+ String destinationPath = unit.destinationPath;
+ if (destinationPath == null) {
+ destinationPath = this.main.destinationPath;
+ }
+ if (destinationPath != null && destinationPath != NONE) {
+ if (File.separatorChar == '/') {
+ this.parameters.put(Logger.OUTPUT, destinationPath);
+ } else {
+ this.parameters.put(Logger.OUTPUT, destinationPath.replace('/', File.separatorChar));
+ }
+ }
+ }
+ printTag(Logger.SOURCE, this.parameters, true, false);
+ }
+ }
+
+ public void startLoggingSources() {
+ if ((this.tagBits & Logger.XML) != 0) {
+ printTag(Logger.SOURCES, null, true, false);
+ }
+ }
+
+ public void startLoggingTasks(int tasks) {
+ if ((this.tagBits & Logger.XML) != 0) {
+ this.parameters.put(Logger.NUMBER_OF_TASKS, new Integer(tasks));
+ printTag(Logger.TASKS, this.parameters, true, false);
+ }
+ }
+ }
+
+ /**
+ * Resource bundle factory to share bundles for the same locale
+ */
+ public static class ResourceBundleFactory {
+ private static HashMap Cache = new HashMap();
+ public static synchronized ResourceBundle getBundle(Locale locale) {
+ ResourceBundle bundle = (ResourceBundle) Cache.get(locale);
+ if (bundle == null) {
+ bundle = ResourceBundle.getBundle(Main.bundleName, locale);
+ Cache.put(locale, bundle);
+ }
+ return bundle;
+ }
+ }
+ // javadoc analysis tuning
+ boolean enableJavadocOn;
+
+ boolean warnJavadocOn;
+ boolean warnAllJavadocOn;
+
+ public Compiler batchCompiler;
+ /* Bundle containing messages */
+ public ResourceBundle bundle;
+ protected FileSystem.Classpath[] checkedClasspaths;
+
+ public Locale compilerLocale;
+ public CompilerOptions compilerOptions; // read-only
+ public CompilationProgress progress;
+ public String destinationPath;
+ public String[] destinationPaths;
+ // destination path for compilation units that get no more specific
+ // one (through directory arguments or various classpath options);
+ // coding is:
+ // == null: unspecified, write class files close to their respective
+ // source files;
+ // == 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 didSpecifySource;
+ private boolean didSpecifyTarget;
+ public String[] encodings;
+ public int exportedClassFilesCounter;
+ public String[] filenames;
+ public String[] classNames;
+ // overrides of destinationPath on a directory argument basis
+ public int globalErrorsCount;
+ public int globalProblemsCount;
+ public int globalTasksCount;
+ public int globalWarningsCount;
+
+ private File javaHomeCache;
+
+ private boolean javaHomeChecked = false;
+ public long lineCount0;
+
+ public String log;
+
+ public Logger logger;
+ public int maxProblems;
+ public Map options;
+ protected PrintWriter out;
+ public boolean proceed = true;
+ public boolean proceedOnError = false;
+ public boolean produceRefInfo = false;
+ public int currentRepetition, maxRepetition;
+ public boolean showProgress = false;
+ public long startTime;
+ public ArrayList pendingErrors;
+ public boolean systemExitWhenFinished = true;
+
+ public static final int TIMING_DISABLED = 0;
+ public static final int TIMING_ENABLED = 1;
+ public static final int TIMING_DETAILED = 2;
+
+ public int timing = TIMING_DISABLED;
+ public CompilerStats[] compilerStats;
+ public boolean verbose = false;
+ private String[] expandedCommandLine;
+
+ private PrintWriter err;
+
+ ArrayList extraProblems;
+ public final static String bundleName = "org.eclipse.jdt.internal.compiler.batch.messages"; //$NON-NLS-1$
+ // two uses: recognize 'none' in options; code the singleton none
+ // for the '-d none' option (wherever it may be found)
+ public static final int DEFAULT_SIZE_CLASSPATH = 4;
+
+ public static final String NONE = "none"; //$NON-NLS-1$
+
+/**
+ * @deprecated - use {@link BatchCompiler#compile(String, PrintWriter, PrintWriter, CompilationProgress)} instead
+ * e.g. BatchCompiler.compile(commandLine, new PrintWriter(System.out), new PrintWriter(System.err), null);
+ */
+public static boolean compile(String commandLine) {
+ return new Main(new PrintWriter(System.out), new PrintWriter(System.err), false /* systemExit */, null /* options */, null /* progress */).compile(tokenize(commandLine));
+}
+
+/**
+ * @deprecated - use {@link BatchCompiler#compile(String, PrintWriter, PrintWriter, CompilationProgress)} instead
+ * e.g. BatchCompiler.compile(commandLine, outWriter, errWriter, null);
+ */
+public static boolean compile(String commandLine, PrintWriter outWriter, PrintWriter errWriter) {
+ return new Main(outWriter, errWriter, false /* systemExit */, null /* options */, null /* progress */).compile(tokenize(commandLine));
+}
+
+/*
+ * Internal API for public API BatchCompiler#compile(String[], PrintWriter, PrintWriter, CompilationProgress)
+ */
+public static boolean compile(String[] commandLineArguments, PrintWriter outWriter, PrintWriter errWriter, CompilationProgress progress) {
+ return new Main(outWriter, errWriter, false /* systemExit */, null /* options */, progress).compile(commandLineArguments);
+}
+public static File[][] getLibrariesFiles(File[] files) {
+ FilenameFilter filter = new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ return Util.isPotentialZipArchive(name);
+ }
+ };
+ final int filesLength = files.length;
+ File[][] result = new File[filesLength][];
+ for (int i = 0; i < filesLength; i++) {
+ File currentFile = files[i];
+ if (currentFile.exists() && currentFile.isDirectory()) {
+ result[i] = currentFile.listFiles(filter);
+ }
+ }
+ return result;
+}
+
+public static void main(String[] argv) {
+ new Main(new PrintWriter(System.out), new PrintWriter(System.err), true/*systemExit*/, null/*options*/, null/*progress*/).compile(argv);
+}
+
+public static String[] tokenize(String commandLine) {
+
+ int count = 0;
+ String[] arguments = new String[10];
+ StringTokenizer tokenizer = new StringTokenizer(commandLine, " \"", true); //$NON-NLS-1$
+ String token = Util.EMPTY_STRING;
+ boolean insideQuotes = false;
+ boolean startNewToken = true;
+
+ // take care to quotes on the command line
+ // 'xxx "aaa bbb";ccc yyy' ---> {"xxx", "aaa bbb;ccc", "yyy" }
+ // 'xxx "aaa bbb;ccc" yyy' ---> {"xxx", "aaa bbb;ccc", "yyy" }
+ // 'xxx "aaa bbb";"ccc" yyy' ---> {"xxx", "aaa bbb;ccc", "yyy" }
+ // 'xxx/"aaa bbb";"ccc" yyy' ---> {"xxx/aaa bbb;ccc", "yyy" }
+ while (tokenizer.hasMoreTokens()) {
+ token = tokenizer.nextToken();
+
+ if (token.equals(" ")) { //$NON-NLS-1$
+ if (insideQuotes) {
+ arguments[count - 1] += token;
+ startNewToken = false;
+ } else {
+ startNewToken = true;
+ }
+ } else if (token.equals("\"")) { //$NON-NLS-1$
+ if (!insideQuotes && startNewToken) {
+ if (count == arguments.length)
+ System.arraycopy(arguments, 0, (arguments = new String[count * 2]), 0, count);
+ arguments[count++] = Util.EMPTY_STRING;
+ }
+ insideQuotes = !insideQuotes;
+ startNewToken = false;
+ } else {
+ if (insideQuotes) {
+ arguments[count - 1] += token;
+ } else {
+ if (token.length() > 0 && !startNewToken) {
+ arguments[count - 1] += token;
+ } else {
+ if (count == arguments.length)
+ System.arraycopy(arguments, 0, (arguments = new String[count * 2]), 0, count);
+ String trimmedToken = token.trim();
+ if (trimmedToken.length() != 0) {
+ arguments[count++] = trimmedToken;
+ }
+ }
+ }
+ startNewToken = false;
+ }
+ }
+ System.arraycopy(arguments, 0, arguments = new String[count], 0, count);
+ return arguments;
+}
+
+/**
+ * @deprecated - use {@link #Main(PrintWriter, PrintWriter, boolean, Map, CompilationProgress)} instead
+ * e.g. Main(outWriter, errWriter, systemExitWhenFinished, null, null)
+ */
+public Main(PrintWriter outWriter, PrintWriter errWriter, boolean systemExitWhenFinished) {
+ this(outWriter, errWriter, systemExitWhenFinished, null /* options */, null /* progress */);
+}
+
+/**
+ * @deprecated - use {@link #Main(PrintWriter, PrintWriter, boolean, Map, CompilationProgress)} instead
+ * e.g. Main(outWriter, errWriter, systemExitWhenFinished, customDefaultOptions, null)
+ */
+public Main(PrintWriter outWriter, PrintWriter errWriter, boolean systemExitWhenFinished, Map customDefaultOptions) {
+ this(outWriter, errWriter, systemExitWhenFinished, customDefaultOptions, null /* progress */);
+}
+
+public Main(PrintWriter outWriter, PrintWriter errWriter, boolean systemExitWhenFinished, Map customDefaultOptions, CompilationProgress compilationProgress) {
+ this.initialize(outWriter, errWriter, systemExitWhenFinished, customDefaultOptions, compilationProgress);
+ this.relocalize();
+}
+
+public void addExtraProblems(CategorizedProblem problem) {
+ if (this.extraProblems == null) {
+ this.extraProblems = new ArrayList();
+ }
+ this.extraProblems.add(problem);
+}
+protected void addNewEntry(ArrayList paths, String currentClasspathName,
+ ArrayList currentRuleSpecs, String customEncoding,
+ String destPath, boolean isSourceOnly,
+ boolean rejectDestinationPathOnJars) {
+
+ int rulesSpecsSize = currentRuleSpecs.size();
+ AccessRuleSet accessRuleSet = null;
+ if (rulesSpecsSize != 0) {
+ AccessRule[] accessRules = new AccessRule[currentRuleSpecs.size()];
+ boolean rulesOK = true;
+ Iterator i = currentRuleSpecs.iterator();
+ int j = 0;
+ while (i.hasNext()) {
+ String ruleSpec = (String) i.next();
+ char key = ruleSpec.charAt(0);
+ String pattern = ruleSpec.substring(1);
+ if (pattern.length() > 0) {
+ switch (key) {
+ case '+':
+ accessRules[j++] = new AccessRule(pattern
+ .toCharArray(), 0);
+ break;
+ case '~':
+ accessRules[j++] = new AccessRule(pattern
+ .toCharArray(),
+ IProblem.DiscouragedReference);
+ break;
+ case '-':
+ accessRules[j++] = new AccessRule(pattern
+ .toCharArray(),
+ IProblem.ForbiddenReference);
+ break;
+ case '?':
+ accessRules[j++] = new AccessRule(pattern
+ .toCharArray(),
+ IProblem.ForbiddenReference, true/*keep looking for accessible type*/);
+ break;
+ default:
+ rulesOK = false;
+ }
+ } else {
+ rulesOK = false;
+ }
+ }
+ if (rulesOK) {
+ accessRuleSet = new AccessRuleSet(accessRules, AccessRestriction.COMMAND_LINE, currentClasspathName);
+ } else {
+ if (currentClasspathName.length() != 0) {
+ // we go on anyway
+ addPendingErrors(this.bind("configure.incorrectClasspath", currentClasspathName));//$NON-NLS-1$
+ }
+ return;
+ }
+ }
+ if (NONE.equals(destPath)) {
+ destPath = NONE; // keep == comparison valid
+ }
+ if (rejectDestinationPathOnJars && destPath != null &&
+ Util.isPotentialZipArchive(currentClasspathName)) {
+ throw new IllegalArgumentException(
+ this.bind("configure.unexpectedDestinationPathEntryFile", //$NON-NLS-1$
+ currentClasspathName));
+ }
+ FileSystem.Classpath currentClasspath = FileSystem.getClasspath(
+ currentClasspathName,
+ customEncoding,
+ isSourceOnly,
+ accessRuleSet,
+ destPath);
+ if (currentClasspath != null) {
+ paths.add(currentClasspath);
+ } else if (currentClasspathName.length() != 0) {
+ // we go on anyway
+ addPendingErrors(this.bind("configure.incorrectClasspath", currentClasspathName));//$NON-NLS-1$
+ }
+}
+void addPendingErrors(String message) {
+ if (this.pendingErrors == null) {
+ this.pendingErrors = new ArrayList();
+ }
+ this.pendingErrors.add(message);
+}
+/*
+ * Lookup the message with the given ID in this catalog
+ */
+public String bind(String id) {
+ return bind(id, (String[]) null);
+}
+/*
+ * Lookup the message with the given ID in this catalog and bind its
+ * substitution locations with the given string.
+ */
+public String bind(String id, String binding) {
+ return bind(id, new String[] { binding });
+}
+
+/*
+ * Lookup the message with the given ID in this catalog and bind its
+ * substitution locations with the given strings.
+ */
+public String bind(String id, String binding1, String binding2) {
+ return bind(id, new String[] { binding1, binding2 });
+}
+
+/*
+ * Lookup the message with the given ID in this catalog and bind its
+ * substitution locations with the given string values.
+ */
+public String bind(String id, String[] arguments) {
+ if (id == null)
+ return "No message available"; //$NON-NLS-1$
+ String message = null;
+ try {
+ message = this.bundle.getString(id);
+ } catch (MissingResourceException e) {
+ // If we got an exception looking for the message, fail gracefully by just returning
+ // the id we were looking for. In most cases this is semi-informative so is not too bad.
+ return "Missing message: " + id + " in: " + Main.bundleName; //$NON-NLS-2$ //$NON-NLS-1$
+ }
+ return MessageFormat.format(message, arguments);
+}
+/**
+ * Return true if and only if the running VM supports the given minimal version.
+ *
+ * <p>This only checks the major version, since the minor version is always 0 (at least for the useful cases).</p>
+ * <p>The given minimalSupportedVersion is one of the constants:</p>
+ * <ul>
+ * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_1</code></li>
+ * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_2</code></li>
+ * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_3</code></li>
+ * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_4</code></li>
+ * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_5</code></li>
+ * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_6</code></li>
+ * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_7</code></li>
+ * </ul>
+ * @param minimalSupportedVersion the given minimal version
+ * @return true if and only if the running VM supports the given minimal version, false otherwise
+ */
+private boolean checkVMVersion(long minimalSupportedVersion) {
+ // the format of this property is supposed to be xx.x where x are digits.
+ String classFileVersion = System.getProperty("java.class.version"); //$NON-NLS-1$
+ if (classFileVersion == null) {
+ // by default we don't support a class file version we cannot recognize
+ return false;
+ }
+ int index = classFileVersion.indexOf('.');
+ if (index == -1) {
+ // by default we don't support a class file version we cannot recognize
+ return false;
+ }
+ int majorVersion;
+ try {
+ majorVersion = Integer.parseInt(classFileVersion.substring(0, index));
+ } catch (NumberFormatException e) {
+ // by default we don't support a class file version we cannot recognize
+ return false;
+ }
+ switch(majorVersion) {
+ case 45 : // 1.0 and 1.1
+ return ClassFileConstants.JDK1_1 >= minimalSupportedVersion;
+ case 46 : // 1.2
+ return ClassFileConstants.JDK1_2 >= minimalSupportedVersion;
+ case 47 : // 1.3
+ return ClassFileConstants.JDK1_3 >= minimalSupportedVersion;
+ case 48 : // 1.4
+ return ClassFileConstants.JDK1_4 >= minimalSupportedVersion;
+ case 49 : // 1.5
+ return ClassFileConstants.JDK1_5 >= minimalSupportedVersion;
+ case 50 : // 1.6
+ return ClassFileConstants.JDK1_6 >= minimalSupportedVersion;
+ case 51 : // 1.7
+ return ClassFileConstants.JDK1_7 >= minimalSupportedVersion;
+ }
+ // unknown version
+ return false;
+}
+/*
+ * Low-level API performing the actual compilation
+ */
+public boolean compile(String[] argv) {
+
+ // decode command line arguments
+ try {
+ configure(argv);
+ if (this.progress != null)
+ this.progress.begin(this.filenames == null ? 0 : this.filenames.length * this.maxRepetition);
+ if (this.proceed) {
+// if (this.verbose) {
+// System.out.println(new CompilerOptions(this.options));
+// }
+ if (this.showProgress) this.logger.compiling();
+ for (this.currentRepetition = 0; this.currentRepetition < this.maxRepetition; this.currentRepetition++) {
+ this.globalProblemsCount = 0;
+ this.globalErrorsCount = 0;
+ this.globalWarningsCount = 0;
+ this.globalTasksCount = 0;
+ this.exportedClassFilesCounter = 0;
+
+ if (this.maxRepetition > 1) {
+ this.logger.flush();
+ this.logger.logRepetition(this.currentRepetition, this.maxRepetition);
+ }
+ // request compilation
+ performCompilation();
+ }
+ if (this.compilerStats != null) {
+ this.logger.logAverage();
+ }
+ if (this.showProgress) this.logger.printNewLine();
+ }
+ if (this.systemExitWhenFinished) {
+ this.logger.flush();
+ this.logger.close();
+//{ObjectTeams: changed to recognizable error code (was -1)
+/* orig:
+ System.exit(this.globalErrorsCount > 0 ? -1 : 0);
+ :giro*/
+ System.exit(this.globalErrorsCount > 0 ? this.logger._errorCode : 0);
+// SH}
+
+ }
+ } catch (IllegalArgumentException e) {
+ this.logger.logException(e);
+ if (this.systemExitWhenFinished) {
+ this.logger.flush();
+ this.logger.close();
+//{ObjectTeams: changed to recognizable error code
+/* orig:
+ System.exit(-1);
+ :giro */
+ System.exit(-2);
+// SH}
+ }
+ return false;
+ } catch (RuntimeException e) { // internal compiler failure
+ this.logger.logException(e);
+ if (this.systemExitWhenFinished) {
+ this.logger.flush();
+ this.logger.close();
+ System.exit(-1);
+ }
+ return false;
+ } finally {
+ this.logger.flush();
+ this.logger.close();
+ if (this.progress != null)
+ this.progress.done();
+ }
+ if (this.globalErrorsCount == 0 && (this.progress == null || !this.progress.isCanceled()))
+ return true;
+ return false;
+}
+
+/*
+Decode the command line arguments
+ */
+public void configure(String[] argv) {
+
+ if ((argv == null) || (argv.length == 0)) {
+ printUsage();
+ return;
+ }
+
+ final int INSIDE_CLASSPATH_start = 1;
+ final int INSIDE_DESTINATION_PATH = 3;
+ final int INSIDE_TARGET = 4;
+ final int INSIDE_LOG = 5;
+ final int INSIDE_REPETITION = 6;
+ final int INSIDE_SOURCE = 7;
+ final int INSIDE_DEFAULT_ENCODING = 8;
+ final int INSIDE_BOOTCLASSPATH_start = 9;
+ final int INSIDE_MAX_PROBLEMS = 11;
+ final int INSIDE_EXT_DIRS = 12;
+ final int INSIDE_SOURCE_PATH_start = 13;
+ final int INSIDE_ENDORSED_DIRS = 15;
+ final int INSIDE_SOURCE_DIRECTORY_DESTINATION_PATH = 16;
+ final int INSIDE_PROCESSOR_PATH_start = 17;
+ final int INSIDE_PROCESSOR_start = 18;
+ final int INSIDE_S_start = 19;
+ final int INSIDE_CLASS_NAMES = 20;
+
+ final int DEFAULT = 0;
+ ArrayList bootclasspaths = new ArrayList(DEFAULT_SIZE_CLASSPATH);
+ String sourcepathClasspathArg = null;
+ ArrayList sourcepathClasspaths = new ArrayList(DEFAULT_SIZE_CLASSPATH);
+ ArrayList classpaths = new ArrayList(DEFAULT_SIZE_CLASSPATH);
+ ArrayList extdirsClasspaths = null;
+ ArrayList endorsedDirClasspaths = null;
+
+ int index = -1;
+ int filesCount = 0;
+ int classCount = 0;
+ int argCount = argv.length;
+ int mode = DEFAULT;
+ this.maxRepetition = 0;
+ boolean printUsageRequired = false;
+ String usageSection = null;
+ boolean printVersionRequired = false;
+
+ boolean didSpecifyDefaultEncoding = false;
+ boolean didSpecifyDeprecation = false;
+ boolean didSpecifyCompliance = false;
+ boolean didSpecifyDisabledAnnotationProcessing = false;
+
+ String customEncoding = null;
+ String customDestinationPath = null;
+ String currentSourceDirectory = null;
+ String currentArg = Util.EMPTY_STRING;
+
+ // expand the command line if necessary
+ boolean needExpansion = false;
+ loop: for (int i = 0; i < argCount; i++) {
+ if (argv[i].startsWith("@")) { //$NON-NLS-1$
+ needExpansion = true;
+ break loop;
+ }
+ }
+
+ String[] newCommandLineArgs = null;
+ if (needExpansion) {
+ newCommandLineArgs = new String[argCount];
+ index = 0;
+ for (int i = 0; i < argCount; i++) {
+ String[] newArgs = null;
+ String arg = argv[i].trim();
+ if (arg.startsWith("@")) { //$NON-NLS-1$
+ try {
+ LineNumberReader reader = new LineNumberReader(new StringReader(new String(Util.getFileCharContent(new File(arg.substring(1)), null))));
+ StringBuffer buffer = new StringBuffer();
+ String line;
+ while((line = reader.readLine()) != null) {
+ line = line.trim();
+ if (!line.startsWith("#")) { //$NON-NLS-1$
+ buffer.append(line).append(" "); //$NON-NLS-1$
+ }
+ }
+ newArgs = tokenize(buffer.toString());
+ } catch(IOException e) {
+ throw new IllegalArgumentException(
+ this.bind("configure.invalidexpansionargumentname", arg)); //$NON-NLS-1$
+ }
+ }
+ if (newArgs != null) {
+ int newCommandLineArgsLength = newCommandLineArgs.length;
+ int newArgsLength = newArgs.length;
+ System.arraycopy(newCommandLineArgs, 0, (newCommandLineArgs = new String[newCommandLineArgsLength + newArgsLength - 1]), 0, index);
+ System.arraycopy(newArgs, 0, newCommandLineArgs, index, newArgsLength);
+ index += newArgsLength;
+ } else {
+ newCommandLineArgs[index++] = arg;
+ }
+ }
+ index = -1;
+ } else {
+ newCommandLineArgs = argv;
+ for (int i = 0; i < argCount; i++) {
+ newCommandLineArgs[i] = newCommandLineArgs[i].trim();
+ }
+ }
+ argCount = newCommandLineArgs.length;
+ this.expandedCommandLine = newCommandLineArgs;
+ while (++index < argCount) {
+
+ if (customEncoding != null) {
+ throw new IllegalArgumentException(
+ this.bind("configure.unexpectedCustomEncoding", currentArg, customEncoding)); //$NON-NLS-1$
+ }
+
+ currentArg = newCommandLineArgs[index];
+
+ switch(mode) {
+ case DEFAULT :
+ if (currentArg.startsWith("[")) { //$NON-NLS-1$
+ throw new IllegalArgumentException(
+ this.bind("configure.unexpectedBracket", //$NON-NLS-1$
+ currentArg));
+ }
+
+ if (currentArg.endsWith("]")) { //$NON-NLS-1$
+ // look for encoding specification
+ int encodingStart = currentArg.indexOf('[') + 1;
+ if (encodingStart <= 1) {
+ throw new IllegalArgumentException(
+ this.bind("configure.unexpectedBracket", currentArg)); //$NON-NLS-1$
+ }
+ int encodingEnd = currentArg.length() - 1;
+ if (encodingStart >= 1) {
+ if (encodingStart < encodingEnd) {
+ customEncoding = currentArg.substring(encodingStart, encodingEnd);
+ try { // ensure encoding is supported
+ new InputStreamReader(new ByteArrayInputStream(new byte[0]), customEncoding);
+ } catch (UnsupportedEncodingException e) {
+ throw new IllegalArgumentException(
+ this.bind("configure.unsupportedEncoding", customEncoding)); //$NON-NLS-1$
+ }
+ }
+ currentArg = currentArg.substring(0, encodingStart - 1);
+ }
+ }
+
+ if (currentArg.endsWith(SuffixConstants.SUFFIX_STRING_java)) {
+ if (this.filenames == null) {
+ this.filenames = new String[argCount - index];
+ this.encodings = new String[argCount - index];
+ this.destinationPaths = new String[argCount - index];
+ } else if (filesCount == this.filenames.length) {
+ int length = this.filenames.length;
+ System.arraycopy(
+ this.filenames,
+ 0,
+ (this.filenames = new String[length + argCount - index]),
+ 0,
+ length);
+ System.arraycopy(
+ this.encodings,
+ 0,
+ (this.encodings = new String[length + argCount - index]),
+ 0,
+ length);
+ System.arraycopy(
+ this.destinationPaths,
+ 0,
+ (this.destinationPaths = new String[length + argCount - index]),
+ 0,
+ length);
+ }
+ this.filenames[filesCount] = currentArg;
+ this.encodings[filesCount++] = customEncoding;
+ // destination path cannot be specified upon an individual file
+ customEncoding = null;
+ mode = DEFAULT;
+ continue;
+ }
+ if (currentArg.equals("-log")) { //$NON-NLS-1$
+ if (this.log != null)
+ throw new IllegalArgumentException(
+ this.bind("configure.duplicateLog", currentArg)); //$NON-NLS-1$
+ mode = INSIDE_LOG;
+ continue;
+ }
+ if (currentArg.equals("-repeat")) { //$NON-NLS-1$
+ if (this.maxRepetition > 0)
+ throw new IllegalArgumentException(
+ this.bind("configure.duplicateRepeat", currentArg)); //$NON-NLS-1$
+ mode = INSIDE_REPETITION;
+ continue;
+ }
+ if (currentArg.equals("-maxProblems")) { //$NON-NLS-1$
+ if (this.maxProblems > 0)
+ throw new IllegalArgumentException(
+ this.bind("configure.duplicateMaxProblems", currentArg)); //$NON-NLS-1$
+ mode = INSIDE_MAX_PROBLEMS;
+ continue;
+ }
+ if (currentArg.equals("-source")) { //$NON-NLS-1$
+ mode = INSIDE_SOURCE;
+ continue;
+ }
+ if (currentArg.equals("-encoding")) { //$NON-NLS-1$
+ mode = INSIDE_DEFAULT_ENCODING;
+ continue;
+ }
+ if (currentArg.equals("-1.3")) { //$NON-NLS-1$
+ if (didSpecifyCompliance) {
+ throw new IllegalArgumentException(
+ this.bind("configure.duplicateCompliance", currentArg));//$NON-NLS-1$
+ }
+ didSpecifyCompliance = true;
+ this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_3);
+ mode = DEFAULT;
+ continue;
+ }
+ if (currentArg.equals("-1.4")) { //$NON-NLS-1$
+ if (didSpecifyCompliance) {
+ throw new IllegalArgumentException(
+ this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$
+ }
+ didSpecifyCompliance = true;
+ this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_4);
+ mode = DEFAULT;
+ continue;
+ }
+ if (currentArg.equals("-1.5") || currentArg.equals("-5") || currentArg.equals("-5.0")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ if (didSpecifyCompliance) {
+ throw new IllegalArgumentException(
+ this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$
+ }
+ didSpecifyCompliance = true;
+ this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_5);
+ mode = DEFAULT;
+ continue;
+ }
+ if (currentArg.equals("-1.6") || currentArg.equals("-6") || currentArg.equals("-6.0")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ if (didSpecifyCompliance) {
+ throw new IllegalArgumentException(
+ this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$
+ }
+ didSpecifyCompliance = true;
+ this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_6);
+ mode = DEFAULT;
+ continue;
+ }
+ if (currentArg.equals("-1.7") || currentArg.equals("-7") || currentArg.equals("-7.0")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ if (didSpecifyCompliance) {
+ throw new IllegalArgumentException(
+ this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$
+ }
+ didSpecifyCompliance = true;
+ this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_7);
+ mode = DEFAULT;
+ continue;
+ }
+ if (currentArg.equals("-d")) { //$NON-NLS-1$
+ if (this.destinationPath != null) {
+ StringBuffer errorMessage = new StringBuffer();
+ errorMessage.append(currentArg);
+ if ((index + 1) < argCount) {
+ errorMessage.append(' ');
+ errorMessage.append(newCommandLineArgs[index + 1]);
+ }
+ throw new IllegalArgumentException(
+ this.bind("configure.duplicateOutputPath", errorMessage.toString())); //$NON-NLS-1$
+ }
+ mode = INSIDE_DESTINATION_PATH;
+ continue;
+ }
+ if (currentArg.equals("-classpath") //$NON-NLS-1$
+ || currentArg.equals("-cp")) { //$NON-NLS-1$
+ mode = INSIDE_CLASSPATH_start;
+ continue;
+ }
+ if (currentArg.equals("-bootclasspath")) {//$NON-NLS-1$
+ if (bootclasspaths.size() > 0) {
+ StringBuffer errorMessage = new StringBuffer();
+ errorMessage.append(currentArg);
+ if ((index + 1) < argCount) {
+ errorMessage.append(' ');
+ errorMessage.append(newCommandLineArgs[index + 1]);
+ }
+ throw new IllegalArgumentException(
+ this.bind("configure.duplicateBootClasspath", errorMessage.toString())); //$NON-NLS-1$
+ }
+ mode = INSIDE_BOOTCLASSPATH_start;
+ continue;
+ }
+ if (currentArg.equals("-sourcepath")) {//$NON-NLS-1$
+ if (sourcepathClasspathArg != null) {
+ StringBuffer errorMessage = new StringBuffer();
+ errorMessage.append(currentArg);
+ if ((index + 1) < argCount) {
+ errorMessage.append(' ');
+ errorMessage.append(newCommandLineArgs[index + 1]);
+ }
+ throw new IllegalArgumentException(
+ this.bind("configure.duplicateSourcepath", errorMessage.toString())); //$NON-NLS-1$
+ }
+ mode = INSIDE_SOURCE_PATH_start;
+ continue;
+ }
+ if (currentArg.equals("-extdirs")) {//$NON-NLS-1$
+ if (extdirsClasspaths != null) {
+ StringBuffer errorMessage = new StringBuffer();
+ errorMessage.append(currentArg);
+ if ((index + 1) < argCount) {
+ errorMessage.append(' ');
+ errorMessage.append(newCommandLineArgs[index + 1]);
+ }
+ throw new IllegalArgumentException(
+ this.bind("configure.duplicateExtDirs", errorMessage.toString())); //$NON-NLS-1$
+ }
+ mode = INSIDE_EXT_DIRS;
+ continue;
+ }
+ if (currentArg.equals("-endorseddirs")) { //$NON-NLS-1$
+ if (endorsedDirClasspaths != null) {
+ StringBuffer errorMessage = new StringBuffer();
+ errorMessage.append(currentArg);
+ if ((index + 1) < argCount) {
+ errorMessage.append(' ');
+ errorMessage.append(newCommandLineArgs[index + 1]);
+ }
+ throw new IllegalArgumentException(
+ this.bind("configure.duplicateEndorsedDirs", errorMessage.toString())); //$NON-NLS-1$
+ }
+ mode = INSIDE_ENDORSED_DIRS;
+ continue;
+ }
+ if (currentArg.equals("-progress")) { //$NON-NLS-1$
+ mode = DEFAULT;
+ this.showProgress = true;
+ continue;
+ }
+ if (currentArg.startsWith("-proceedOnError")) { //$NON-NLS-1$
+ mode = DEFAULT;
+ int length = currentArg.length();
+ if (length > 15) {
+ if (currentArg.equals("-proceedOnError:Fatal")) { //$NON-NLS-1$
+ this.options.put(CompilerOptions.OPTION_FatalOptionalError, CompilerOptions.ENABLED);
+ } else {
+ throw new IllegalArgumentException(
+ this.bind("configure.invalidWarningConfiguration", currentArg)); //$NON-NLS-1$
+ }
+ } else {
+ this.options.put(CompilerOptions.OPTION_FatalOptionalError, CompilerOptions.DISABLED);
+ }
+ this.proceedOnError = true;
+ continue;
+ }
+ if (currentArg.equals("-time")) { //$NON-NLS-1$
+ mode = DEFAULT;
+ this.timing = TIMING_ENABLED;
+ continue;
+ }
+ if (currentArg.equals("-time:detail")) { //$NON-NLS-1$
+ mode = DEFAULT;
+ this.timing = TIMING_ENABLED|TIMING_DETAILED;
+ continue;
+ }
+ if (currentArg.equals("-version") //$NON-NLS-1$
+ || currentArg.equals("-v")) { //$NON-NLS-1$
+ this.logger.logVersion(true);
+ this.proceed = false;
+ return;
+ }
+ if (currentArg.equals("-showversion")) { //$NON-NLS-1$
+ printVersionRequired = true;
+ mode = DEFAULT;
+ continue;
+ }
+ if ("-deprecation".equals(currentArg)) { //$NON-NLS-1$
+ didSpecifyDeprecation = true;
+ this.options.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.WARNING);
+ mode = DEFAULT;
+ continue;
+ }
+ if (currentArg.equals("-help") || currentArg.equals("-?")) { //$NON-NLS-1$ //$NON-NLS-2$
+ printUsageRequired = true;
+ mode = DEFAULT;
+ continue;
+ }
+ if (currentArg.equals("-help:warn") || //$NON-NLS-1$
+ currentArg.equals("-?:warn")) { //$NON-NLS-1$
+ printUsageRequired = true;
+ usageSection = "misc.usage.warn"; //$NON-NLS-1$
+ continue;
+ }
+ if (currentArg.equals("-noExit")) { //$NON-NLS-1$
+ this.systemExitWhenFinished = false;
+ mode = DEFAULT;
+ continue;
+ }
+ if (currentArg.equals("-verbose")) { //$NON-NLS-1$
+ this.verbose = true;
+ mode = DEFAULT;
+ continue;
+ }
+ if (currentArg.equals("-referenceInfo")) { //$NON-NLS-1$
+ this.produceRefInfo = true;
+ mode = DEFAULT;
+ continue;
+ }
+ if (currentArg.equals("-inlineJSR")) { //$NON-NLS-1$
+ mode = DEFAULT;
+ this.options.put(
+ CompilerOptions.OPTION_InlineJsr,
+ CompilerOptions.ENABLED);
+ continue;
+ }
+ if (currentArg.startsWith("-g")) { //$NON-NLS-1$
+ mode = DEFAULT;
+ String debugOption = currentArg;
+ int length = currentArg.length();
+ if (length == 2) {
+ this.options.put(
+ CompilerOptions.OPTION_LocalVariableAttribute,
+ CompilerOptions.GENERATE);
+ this.options.put(
+ CompilerOptions.OPTION_LineNumberAttribute,
+ CompilerOptions.GENERATE);
+ this.options.put(
+ CompilerOptions.OPTION_SourceFileAttribute,
+ CompilerOptions.GENERATE);
+ continue;
+ }
+ if (length > 3) {
+ this.options.put(
+ CompilerOptions.OPTION_LocalVariableAttribute,
+ CompilerOptions.DO_NOT_GENERATE);
+ this.options.put(
+ CompilerOptions.OPTION_LineNumberAttribute,
+ CompilerOptions.DO_NOT_GENERATE);
+ this.options.put(
+ CompilerOptions.OPTION_SourceFileAttribute,
+ CompilerOptions.DO_NOT_GENERATE);
+ if (length == 7 && debugOption.equals("-g:" + NONE)) //$NON-NLS-1$
+ continue;
+ StringTokenizer tokenizer =
+ new StringTokenizer(debugOption.substring(3, debugOption.length()), ","); //$NON-NLS-1$
+ while (tokenizer.hasMoreTokens()) {
+ String token = tokenizer.nextToken();
+ if (token.equals("vars")) { //$NON-NLS-1$
+ this.options.put(
+ CompilerOptions.OPTION_LocalVariableAttribute,
+ CompilerOptions.GENERATE);
+ } else if (token.equals("lines")) { //$NON-NLS-1$
+ this.options.put(
+ CompilerOptions.OPTION_LineNumberAttribute,
+ CompilerOptions.GENERATE);
+ } else if (token.equals("source")) { //$NON-NLS-1$
+ this.options.put(
+ CompilerOptions.OPTION_SourceFileAttribute,
+ CompilerOptions.GENERATE);
+ } else {
+ throw new IllegalArgumentException(
+ this.bind("configure.invalidDebugOption", debugOption)); //$NON-NLS-1$
+ }
+ }
+ continue;
+ }
+ 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();
+ continue;
+ }
+ if (length <= 6) {
+ throw new IllegalArgumentException(
+ this.bind("configure.invalidWarningConfiguration", warningOption)); //$NON-NLS-1$
+ }
+ int warnTokenStart;
+ boolean isEnabling, allowPlusOrMinus;
+ 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();
+ warnTokenStart = 6;
+ isEnabling = true;
+ allowPlusOrMinus = false;
+ }
+
+ StringTokenizer tokenizer =
+ new StringTokenizer(warningOption.substring(warnTokenStart, warningOption.length()), ","); //$NON-NLS-1$
+ int tokenCounter = 0;
+
+ if (didSpecifyDeprecation) { // deprecation could have also been set through -deprecation option
+ this.options.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.WARNING);
+ }
+
+ while (tokenizer.hasMoreTokens()) {
+ String token = tokenizer.nextToken();
+ 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$
+ }
+ break;
+ case '-' :
+ if (allowPlusOrMinus) {
+ isEnabling = false;
+ token = token.substring(1);
+ } else {
+ throw new IllegalArgumentException(
+ this.bind("configure.invalidUsageOfMinusOption", token)); //$NON-NLS-1$
+ }
+ }
+ handleWarningToken(token, isEnabling);
+ }
+ if (tokenCounter == 0) {
+ throw new IllegalArgumentException(
+ this.bind("configure.invalidWarningOption", currentArg)); //$NON-NLS-1$
+ }
+ continue;
+ }
+ if (currentArg.startsWith("-err")) { //$NON-NLS-1$
+ mode = DEFAULT;
+ String errorOption = currentArg;
+ int length = currentArg.length();
+ if (length <= 5) {
+ throw new IllegalArgumentException(
+ this.bind("configure.invalidErrorConfiguration", errorOption)); //$NON-NLS-1$
+ }
+ int errorTokenStart;
+ boolean isEnabling, allowPlusOrMinus;
+ 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();
+ errorTokenStart = 5;
+ isEnabling = true;
+ allowPlusOrMinus = false;
+ }
+
+ StringTokenizer tokenizer =
+ new StringTokenizer(errorOption.substring(errorTokenStart, errorOption.length()), ","); //$NON-NLS-1$
+ int tokenCounter = 0;
+
+ while (tokenizer.hasMoreTokens()) {
+ String token = tokenizer.nextToken();
+ 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$
+ }
+ break;
+ case '-' :
+ if (allowPlusOrMinus) {
+ isEnabling = false;
+ token = token.substring(1);
+ } else {
+ throw new IllegalArgumentException(
+ this.bind("configure.invalidUsageOfMinusOption", token)); //$NON-NLS-1$
+ }
+ break;
+ }
+ handleErrorToken(token, isEnabling);
+ }
+ if (tokenCounter == 0) {
+ throw new IllegalArgumentException(
+ this.bind("configure.invalidErrorOption", currentArg)); //$NON-NLS-1$
+ }
+ continue;
+ }
+ if (currentArg.equals("-target")) { //$NON-NLS-1$
+ mode = INSIDE_TARGET;
+ continue;
+ }
+ if (currentArg.equals("-preserveAllLocals")) { //$NON-NLS-1$
+ this.options.put(
+ CompilerOptions.OPTION_PreserveUnusedLocal,
+ CompilerOptions.PRESERVE);
+ mode = DEFAULT;
+ continue;
+ }
+ if (currentArg.equals("-enableJavadoc")) {//$NON-NLS-1$
+ mode = DEFAULT;
+ this.enableJavadocOn = true;
+ continue;
+ }
+ if (currentArg.equals("-Xemacs")) { //$NON-NLS-1$
+ mode = DEFAULT;
+ this.logger.setEmacs();
+ continue;
+ }
+ // annotation processing
+ if (currentArg.startsWith("-A")) { //$NON-NLS-1$
+ mode = DEFAULT;
+ continue;
+ }
+ if (currentArg.equals("-processorpath")) { //$NON-NLS-1$
+ mode = INSIDE_PROCESSOR_PATH_start;
+ continue;
+ }
+ if (currentArg.equals("-processor")) { //$NON-NLS-1$
+ mode = INSIDE_PROCESSOR_start;
+ continue;
+ }
+ if (currentArg.equals("-proc:only")) { //$NON-NLS-1$
+ this.options.put(
+ CompilerOptions.OPTION_GenerateClassFiles,
+ CompilerOptions.DISABLED);
+ mode = DEFAULT;
+ continue;
+ }
+ if (currentArg.equals("-proc:none")) { //$NON-NLS-1$
+ didSpecifyDisabledAnnotationProcessing = true;
+ this.options.put(
+ CompilerOptions.OPTION_Process_Annotations,
+ CompilerOptions.DISABLED);
+ mode = DEFAULT;
+ continue;
+ }
+ if (currentArg.equals("-s")) { //$NON-NLS-1$
+ mode = INSIDE_S_start;
+ continue;
+ }
+ if (currentArg.equals("-XprintProcessorInfo") //$NON-NLS-1$
+ || currentArg.equals("-XprintRounds")) { //$NON-NLS-1$
+ mode = DEFAULT;
+ continue;
+ }
+//{ObjectTeams: specific options:
+ if (currentArg.equals("-decapsulation")) { //$NON-NLS-1$
+ mode = DEFAULT;
+ this.options.put(
+ CompilerOptions.OPTION_Decapsulation,
+ CompilerOptions.REPORT_BINDING);
+ continue;
+ }
+ if (currentArg.equals("-nodecapsulation")) { //$NON-NLS-1$
+ mode = DEFAULT;
+ this.options.put(
+ CompilerOptions.OPTION_Decapsulation,
+ CompilerOptions.REPORT_NONE);
+ continue;
+ }
+// SH}
+ // tolerated javac options - quietly filtered out
+ if (currentArg.startsWith("-X")) { //$NON-NLS-1$
+ mode = DEFAULT;
+ continue;
+ }
+ if (currentArg.startsWith("-J")) { //$NON-NLS-1$
+ mode = DEFAULT;
+ continue;
+ }
+ if (currentArg.equals("-O")) { //$NON-NLS-1$
+ mode = DEFAULT;
+ continue;
+ }
+ if (currentArg.equals("-classNames")) { //$NON-NLS-1$
+ mode = INSIDE_CLASS_NAMES;
+ continue;
+ }
+ break;
+ case INSIDE_TARGET :
+ if (this.didSpecifyTarget) {
+ throw new IllegalArgumentException(
+ this.bind("configure.duplicateTarget", currentArg));//$NON-NLS-1$
+ }
+ this.didSpecifyTarget = true;
+ if (currentArg.equals("1.1")) { //$NON-NLS-1$
+ this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_1);
+ } else if (currentArg.equals("1.2")) { //$NON-NLS-1$
+ this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_2);
+ } else if (currentArg.equals("1.3")) { //$NON-NLS-1$
+ this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_3);
+ } else if (currentArg.equals("1.4")) { //$NON-NLS-1$
+ this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
+ } else if (currentArg.equals("1.5") || currentArg.equals("5") || currentArg.equals("5.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
+ this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5);
+ } else if (currentArg.equals("1.6") || currentArg.equals("6") || currentArg.equals("6.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
+ this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
+ } else if (currentArg.equals("1.7") || currentArg.equals("7") || currentArg.equals("7.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
+ this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7);
+ } else if (currentArg.equals("jsr14")) { //$NON-NLS-1$
+ this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_JSR14);
+ } else if (currentArg.equals("cldc1.1")) { //$NON-NLS-1$
+ this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_CLDC1_1);
+ this.options.put(CompilerOptions.OPTION_InlineJsr, CompilerOptions.ENABLED);
+ }else {
+ throw new IllegalArgumentException(this.bind("configure.targetJDK", currentArg)); //$NON-NLS-1$
+ }
+ mode = DEFAULT;
+ continue;
+ case INSIDE_LOG :
+ this.log = currentArg;
+ mode = DEFAULT;
+ continue;
+ case INSIDE_REPETITION :
+ try {
+ this.maxRepetition = Integer.parseInt(currentArg);
+ if (this.maxRepetition <= 0) {
+ throw new IllegalArgumentException(this.bind("configure.repetition", currentArg)); //$NON-NLS-1$
+ }
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException(this.bind("configure.repetition", currentArg)); //$NON-NLS-1$
+ }
+ mode = DEFAULT;
+ continue;
+ case INSIDE_MAX_PROBLEMS :
+ try {
+ this.maxProblems = Integer.parseInt(currentArg);
+ if (this.maxProblems <= 0) {
+ throw new IllegalArgumentException(this.bind("configure.maxProblems", currentArg)); //$NON-NLS-1$
+ }
+ this.options.put(CompilerOptions.OPTION_MaxProblemPerUnit, currentArg);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException(this.bind("configure.maxProblems", currentArg)); //$NON-NLS-1$
+ }
+ mode = DEFAULT;
+ continue;
+ case INSIDE_SOURCE :
+ if (this.didSpecifySource) {
+ throw new IllegalArgumentException(
+ this.bind("configure.duplicateSource", currentArg));//$NON-NLS-1$
+ }
+ this.didSpecifySource = true;
+ if (currentArg.equals("1.3")) { //$NON-NLS-1$
+ this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3);
+ } else if (currentArg.equals("1.4")) { //$NON-NLS-1$
+ this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_4);
+ } else if (currentArg.equals("1.5") || currentArg.equals("5") || currentArg.equals("5.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
+ this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5);
+ } else if (currentArg.equals("1.6") || currentArg.equals("6") || currentArg.equals("6.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
+ this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_6);
+ } else if (currentArg.equals("1.7") || currentArg.equals("7") || currentArg.equals("7.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
+ this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_7);
+ } else {
+ throw new IllegalArgumentException(this.bind("configure.source", currentArg)); //$NON-NLS-1$
+ }
+ mode = DEFAULT;
+ continue;
+ case INSIDE_DEFAULT_ENCODING :
+ if (didSpecifyDefaultEncoding) {
+ throw new IllegalArgumentException(
+ this.bind("configure.duplicateDefaultEncoding", currentArg)); //$NON-NLS-1$
+ }
+ try { // ensure encoding is supported
+ new InputStreamReader(new ByteArrayInputStream(new byte[0]), currentArg);
+ } catch (UnsupportedEncodingException e) {
+ throw new IllegalArgumentException(
+ this.bind("configure.unsupportedEncoding", currentArg)); //$NON-NLS-1$
+ }
+ this.options.put(CompilerOptions.OPTION_Encoding, currentArg);
+ didSpecifyDefaultEncoding = true;
+ mode = DEFAULT;
+ continue;
+ case INSIDE_DESTINATION_PATH :
+ setDestinationPath(currentArg.equals(NONE) ? NONE : currentArg);
+ mode = DEFAULT;
+ continue;
+ case INSIDE_CLASSPATH_start:
+ mode = DEFAULT;
+ index += processPaths(newCommandLineArgs, index, currentArg, classpaths);
+ continue;
+ case INSIDE_BOOTCLASSPATH_start:
+ mode = DEFAULT;
+ index += processPaths(newCommandLineArgs, index, currentArg, bootclasspaths);
+ continue;
+ case INSIDE_SOURCE_PATH_start:
+ mode = DEFAULT;
+ String[] sourcePaths = new String[1];
+ index += processPaths(newCommandLineArgs, index, currentArg, sourcePaths);
+ sourcepathClasspathArg = sourcePaths[0];
+ continue;
+ case INSIDE_EXT_DIRS:
+ if (currentArg.indexOf("[-d") != -1) { //$NON-NLS-1$
+ throw new IllegalArgumentException(
+ this.bind("configure.unexpectedDestinationPathEntry", //$NON-NLS-1$
+ "-extdir")); //$NON-NLS-1$
+ }
+ StringTokenizer tokenizer = new StringTokenizer(currentArg, File.pathSeparator, false);
+ extdirsClasspaths = new ArrayList(DEFAULT_SIZE_CLASSPATH);
+ while (tokenizer.hasMoreTokens())
+ extdirsClasspaths.add(tokenizer.nextToken());
+ mode = DEFAULT;
+ continue;
+ case INSIDE_ENDORSED_DIRS:
+ if (currentArg.indexOf("[-d") != -1) { //$NON-NLS-1$
+ throw new IllegalArgumentException(
+ this.bind("configure.unexpectedDestinationPathEntry", //$NON-NLS-1$
+ "-endorseddirs")); //$NON-NLS-1$
+ } tokenizer = new StringTokenizer(currentArg, File.pathSeparator, false);
+ endorsedDirClasspaths = new ArrayList(DEFAULT_SIZE_CLASSPATH);
+ while (tokenizer.hasMoreTokens())
+ endorsedDirClasspaths.add(tokenizer.nextToken());
+ mode = DEFAULT;
+ continue;
+ case INSIDE_SOURCE_DIRECTORY_DESTINATION_PATH:
+ if (currentArg.endsWith("]")) { //$NON-NLS-1$
+ customDestinationPath = currentArg.substring(0,
+ currentArg.length() - 1);
+ } else {
+ throw new IllegalArgumentException(
+ this.bind("configure.incorrectDestinationPathEntry", //$NON-NLS-1$
+ "[-d " + currentArg)); //$NON-NLS-1$
+ }
+ break;
+ case INSIDE_PROCESSOR_PATH_start :
+ // nothing to do here. This is consumed again by the AnnotationProcessorManager
+ mode = DEFAULT;
+ continue;
+ case INSIDE_PROCESSOR_start :
+ // nothing to do here. This is consumed again by the AnnotationProcessorManager
+ mode = DEFAULT;
+ continue;
+ case INSIDE_S_start :
+ // nothing to do here. This is consumed again by the AnnotationProcessorManager
+ mode = DEFAULT;
+ continue;
+ case INSIDE_CLASS_NAMES :
+ tokenizer = new StringTokenizer(currentArg, ","); //$NON-NLS-1$
+ if (this.classNames == null) {
+ this.classNames = new String[DEFAULT_SIZE_CLASSPATH];
+ }
+ while (tokenizer.hasMoreTokens()) {
+ if (this.classNames.length == classCount) {
+ // resize
+ System.arraycopy(
+ this.classNames,
+ 0,
+ (this.classNames = new String[classCount * 2]),
+ 0,
+ classCount);
+ }
+ this.classNames[classCount++] = tokenizer.nextToken();
+ }
+ mode = DEFAULT;
+ continue;
+ }
+
+ // default is input directory, if no custom destination path exists
+ if (customDestinationPath == null) {
+ if (File.separatorChar != '/') {
+ currentArg = currentArg.replace('/', File.separatorChar);
+ }
+ if (currentArg.endsWith("[-d")) { //$NON-NLS-1$
+ currentSourceDirectory = currentArg.substring(0,
+ currentArg.length() - 3);
+ mode = INSIDE_SOURCE_DIRECTORY_DESTINATION_PATH;
+ continue;
+ }
+ currentSourceDirectory = currentArg;
+ }
+ File dir = new File(currentSourceDirectory);
+ if (!dir.isDirectory()) {
+ throw new IllegalArgumentException(
+ this.bind("configure.unrecognizedOption", currentSourceDirectory)); //$NON-NLS-1$
+ }
+ String[] result = FileFinder.find(dir, SuffixConstants.SUFFIX_STRING_JAVA);
+ if (NONE.equals(customDestinationPath)) {
+ customDestinationPath = NONE; // ensure == comparison
+ }
+ if (this.filenames != null) {
+ // some source files were specified explicitly
+ int length = result.length;
+ System.arraycopy(
+ this.filenames,
+ 0,
+ (this.filenames = new String[length + filesCount]),
+ 0,
+ filesCount);
+ System.arraycopy(
+ this.encodings,
+ 0,
+ (this.encodings = new String[length + filesCount]),
+ 0,
+ filesCount);
+ System.arraycopy(
+ this.destinationPaths,
+ 0,
+ (this.destinationPaths = new String[length + filesCount]),
+ 0,
+ filesCount);
+ System.arraycopy(result, 0, this.filenames, filesCount, length);
+ for (int i = 0; i < length; i++) {
+ this.encodings[filesCount + i] = customEncoding;
+ this.destinationPaths[filesCount + i] = customDestinationPath;
+ }
+ filesCount += length;
+ customEncoding = null;
+ customDestinationPath = null;
+ currentSourceDirectory = null;
+ } else {
+ this.filenames = result;
+ filesCount = this.filenames.length;
+ this.encodings = new String[filesCount];
+ this.destinationPaths = new String[filesCount];
+ for (int i = 0; i < filesCount; i++) {
+ this.encodings[i] = customEncoding;
+ this.destinationPaths[i] = customDestinationPath;
+ }
+ customEncoding = null;
+ customDestinationPath = null;
+ currentSourceDirectory = null;
+ }
+ mode = DEFAULT;
+ continue;
+ }
+
+ // set DocCommentSupport, with appropriate side effects on defaults if
+ // javadoc is not enabled
+ if (this.enableJavadocOn) {
+ this.options.put(
+ CompilerOptions.OPTION_DocCommentSupport,
+ CompilerOptions.ENABLED);
+ } else if (this.warnJavadocOn || this.warnAllJavadocOn) {
+ this.options.put(
+ CompilerOptions.OPTION_DocCommentSupport,
+ CompilerOptions.ENABLED);
+ // override defaults: references that are embedded in javadoc are ignored
+ // from the perspective of parameters and thrown exceptions usage
+ this.options.put(
+ CompilerOptions.OPTION_ReportUnusedParameterIncludeDocCommentReference,
+ CompilerOptions.DISABLED);
+ this.options.put(
+ CompilerOptions.OPTION_ReportUnusedDeclaredThrownExceptionIncludeDocCommentReference,
+ CompilerOptions.DISABLED);
+ }
+ // configure warnings for javadoc contents
+ if (this.warnJavadocOn) {
+ this.options.put(
+ CompilerOptions.OPTION_ReportInvalidJavadocTags,
+ CompilerOptions.ENABLED);
+ this.options.put(
+ CompilerOptions.OPTION_ReportInvalidJavadocTagsDeprecatedRef,
+ CompilerOptions.ENABLED);
+ this.options.put(
+ CompilerOptions.OPTION_ReportInvalidJavadocTagsNotVisibleRef,
+ CompilerOptions.ENABLED);
+ this.options.put(
+ CompilerOptions.OPTION_ReportMissingJavadocTagsVisibility,
+ CompilerOptions.PRIVATE);
+ }
+
+ if (printUsageRequired || (filesCount == 0 && classCount == 0)) {
+ if (usageSection == null) {
+ printUsage(); // default
+ } else {
+ printUsage(usageSection);
+ }
+ this.proceed = false;
+ return;
+ }
+
+ if (this.log != null) {
+ this.logger.setLog(this.log);
+ } else {
+ this.showProgress = false;
+ }
+ this.logger.logVersion(printVersionRequired);
+
+ validateOptions(didSpecifyCompliance);
+
+ // Enable annotation processing by default in batch mode when compliance is at least 1.6
+ // see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=185768
+ if (!didSpecifyDisabledAnnotationProcessing
+ && CompilerOptions.versionToJdkLevel(this.options.get(CompilerOptions.OPTION_Compliance)) >= ClassFileConstants.JDK1_6) {
+ this.options.put(CompilerOptions.OPTION_Process_Annotations, CompilerOptions.ENABLED);
+ }
+
+ this.logger.logCommandLineArguments(newCommandLineArgs);
+ this.logger.logOptions(this.options);
+
+ if (this.maxRepetition == 0) {
+ this.maxRepetition = 1;
+ }
+ if (this.maxRepetition >= 3 && (this.timing & TIMING_ENABLED) != 0) {
+ this.compilerStats = new CompilerStats[this.maxRepetition];
+ }
+
+ if (filesCount != 0) {
+ System.arraycopy(
+ this.filenames,
+ 0,
+ (this.filenames = new String[filesCount]),
+ 0,
+ filesCount);
+ }
+
+ if (classCount != 0) {
+ System.arraycopy(
+ this.classNames,
+ 0,
+ (this.classNames = new String[classCount]),
+ 0,
+ classCount);
+ }
+
+ setPaths(bootclasspaths,
+ sourcepathClasspathArg,
+ sourcepathClasspaths,
+ classpaths,
+ extdirsClasspaths,
+ endorsedDirClasspaths,
+ customEncoding);
+
+ if (this.pendingErrors != null) {
+ for (Iterator iterator = this.pendingErrors.iterator(); iterator.hasNext(); ) {
+ String message = (String) iterator.next();
+ this.logger.logPendingError(message);
+ }
+ this.pendingErrors = null;
+ }
+}
+protected void disableWarnings() {
+ Object[] entries = this.options.entrySet().toArray();
+ for (int i = 0, max = entries.length; i < max; i++) {
+ Map.Entry entry = (Map.Entry) entries[i];
+ if (!(entry.getKey() instanceof String))
+ continue;
+ if (!(entry.getValue() instanceof String))
+ continue;
+ if (((String) entry.getValue()).equals(CompilerOptions.WARNING)) {
+ this.options.put(entry.getKey(), CompilerOptions.IGNORE);
+ }
+ }
+ this.options.put(CompilerOptions.OPTION_TaskTags, Util.EMPTY_STRING);
+}
+protected void disableErrors() {
+ Object[] entries = this.options.entrySet().toArray();
+ for (int i = 0, max = entries.length; i < max; i++) {
+ Map.Entry entry = (Map.Entry) entries[i];
+ if (!(entry.getKey() instanceof String))
+ continue;
+ if (!(entry.getValue() instanceof String))
+ continue;
+ if (((String) entry.getValue()).equals(CompilerOptions.ERROR)) {
+ this.options.put(entry.getKey(), CompilerOptions.IGNORE);
+ }
+ }
+}
+public String extractDestinationPathFromSourceFile(CompilationResult result) {
+ ICompilationUnit compilationUnit = result.compilationUnit;
+ if (compilationUnit != null) {
+ char[] fileName = compilationUnit.getFileName();
+ int lastIndex = CharOperation.lastIndexOf(java.io.File.separatorChar, fileName);
+ if (lastIndex != -1) {
+//{ObjectTeams: role files strip last dir(s):
+/* orig:
+ final String outputPathName = new String(fileName, 0, lastIndex);
+ :giro */
+ String outputPathName = new String(fileName, 0, lastIndex);
+ outputPathName= result.stripTeamPackagesFromPath(outputPathName);
+// SH}
+ final File output = new File(outputPathName);
+ if (output.exists() && output.isDirectory()) {
+ return outputPathName;
+ }
+ }
+ }
+ return System.getProperty("user.dir"); //$NON-NLS-1$
+}
+/*
+ * Answer the component to which will be handed back compilation results from the compiler
+ */
+public ICompilerRequestor getBatchRequestor() {
+ return new ICompilerRequestor() {
+ int lineDelta = 0;
+ public void acceptResult(CompilationResult compilationResult) {
+ if (compilationResult.lineSeparatorPositions != null) {
+ int unitLineCount = compilationResult.lineSeparatorPositions.length;
+ this.lineDelta += unitLineCount;
+ if (Main.this.showProgress && this.lineDelta > 2000) {
+ // in -log mode, dump a dot every 2000 lines compiled
+ Main.this.logger.logProgress();
+ this.lineDelta = 0;
+ }
+ }
+ Main.this.logger.startLoggingSource(compilationResult);
+ if (compilationResult.hasProblems() || compilationResult.hasTasks()) {
+ Main.this.logger.logProblems(compilationResult.getAllProblems(), compilationResult.compilationUnit.getContents(), Main.this);
+ }
+ outputClassFiles(compilationResult);
+ Main.this.logger.endLoggingSource();
+ }
+ };
+}
+/*
+ * Build the set of compilation source units
+ */
+public CompilationUnit[] getCompilationUnits() {
+ int fileCount = this.filenames.length;
+ CompilationUnit[] units = new CompilationUnit[fileCount];
+ HashtableOfObject knownFileNames = new HashtableOfObject(fileCount);
+
+ String defaultEncoding = (String) this.options.get(CompilerOptions.OPTION_Encoding);
+ if (Util.EMPTY_STRING.equals(defaultEncoding))
+ defaultEncoding = null;
+
+ for (int i = 0; i < fileCount; i++) {
+ char[] charName = this.filenames[i].toCharArray();
+ if (knownFileNames.get(charName) != null)
+ throw new IllegalArgumentException(this.bind("unit.more", this.filenames[i])); //$NON-NLS-1$
+ knownFileNames.put(charName, charName);
+ File file = new File(this.filenames[i]);
+ if (!file.exists())
+ throw new IllegalArgumentException(this.bind("unit.missing", this.filenames[i])); //$NON-NLS-1$
+ String encoding = this.encodings[i];
+ if (encoding == null)
+ encoding = defaultEncoding;
+ units[i] = new CompilationUnit(null, this.filenames[i], encoding,
+ this.destinationPaths[i]);
+ }
+ return units;
+}
+
+/*
+ * Low-level API performing the actual compilation
+ */
+public IErrorHandlingPolicy getHandlingPolicy() {
+
+ // passes the initial set of files to the batch oracle (to avoid finding more than once the same units when case insensitive match)
+ return new IErrorHandlingPolicy() {
+ public boolean proceedOnErrors() {
+ return Main.this.proceedOnError; // stop if there are some errors
+ }
+ public boolean stopOnFirstError() {
+ return false;
+ }
+ };
+}
+
+/*
+ * External API
+ */
+public File getJavaHome() {
+ if (!this.javaHomeChecked) {
+ this.javaHomeChecked = true;
+ String javaHome = System.getProperty("java.home");//$NON-NLS-1$
+ if (javaHome != null) {
+ this.javaHomeCache = new File(javaHome);
+ if (!this.javaHomeCache.exists())
+ this.javaHomeCache = null;
+ }
+ }
+ return this.javaHomeCache;
+}
+
+public FileSystem getLibraryAccess() {
+ return new FileSystem(this.checkedClasspaths, this.filenames);
+}
+
+/*
+ * Low-level API performing the actual compilation
+ */
+public IProblemFactory getProblemFactory() {
+ return new DefaultProblemFactory(this.compilerLocale);
+}
+
+/*
+ * External API
+ */
+protected ArrayList handleBootclasspath(ArrayList bootclasspaths, String customEncoding) {
+ final int bootclasspathsSize = bootclasspaths == null ? 0 : bootclasspaths.size();
+ if (bootclasspathsSize != 0) {
+ String[] paths = new String[bootclasspathsSize];
+ bootclasspaths.toArray(paths);
+ bootclasspaths.clear();
+ for (int i = 0; i < bootclasspathsSize; i++) {
+ processPathEntries(DEFAULT_SIZE_CLASSPATH, bootclasspaths,
+ paths[i], customEncoding, false, true);
+ }
+ } else {
+ bootclasspaths = new ArrayList(DEFAULT_SIZE_CLASSPATH);
+ /* no bootclasspath specified
+ * we can try to retrieve the default librairies of the VM used to run
+ * the batch compiler
+ */
+ String javaversion = System.getProperty("java.version");//$NON-NLS-1$
+ if (javaversion != null && javaversion.equalsIgnoreCase("1.1.8")) { //$NON-NLS-1$
+ this.logger.logWrongJDK();
+ this.proceed = false;
+ return null;
+ }
+
+ /*
+ * Handle >= JDK 1.2.2 settings: retrieve the bootclasspath
+ */
+ // check bootclasspath properties for Sun, JRockit and Harmony VMs
+ String bootclasspathProperty = System.getProperty("sun.boot.class.path"); //$NON-NLS-1$
+ if ((bootclasspathProperty == null) || (bootclasspathProperty.length() == 0)) {
+ // IBM J9 VMs
+ bootclasspathProperty = System.getProperty("vm.boot.class.path"); //$NON-NLS-1$
+ if ((bootclasspathProperty == null) || (bootclasspathProperty.length() == 0)) {
+ // Harmony using IBM VME
+ bootclasspathProperty = System.getProperty("org.apache.harmony.boot.class.path"); //$NON-NLS-1$
+ }
+ }
+ if ((bootclasspathProperty != null) && (bootclasspathProperty.length() != 0)) {
+ StringTokenizer tokenizer = new StringTokenizer(bootclasspathProperty, File.pathSeparator);
+ String token;
+ while (tokenizer.hasMoreTokens()) {
+ token = tokenizer.nextToken();
+ FileSystem.Classpath currentClasspath = FileSystem
+ .getClasspath(token, customEncoding, null);
+ if (currentClasspath != null) {
+ bootclasspaths.add(currentClasspath);
+ }
+ }
+ } else {
+ // try to get all jars inside the lib folder of the java home
+ final File javaHome = getJavaHome();
+ if (javaHome != null) {
+ File[] directoriesToCheck = null;
+ if (System.getProperty("os.name").startsWith("Mac")) {//$NON-NLS-1$//$NON-NLS-2$
+ directoriesToCheck = new File[] {
+ new File(javaHome, "../Classes"), //$NON-NLS-1$
+ };
+ } else {
+ // fall back to try to retrieve them out of the lib directory
+ directoriesToCheck = new File[] {
+ new File(javaHome, "lib") //$NON-NLS-1$
+ };
+ }
+ File[][] systemLibrariesJars = getLibrariesFiles(directoriesToCheck);
+ if (systemLibrariesJars != null) {
+ for (int i = 0, max = systemLibrariesJars.length; i < max; i++) {
+ File[] current = systemLibrariesJars[i];
+ if (current != null) {
+ for (int j = 0, max2 = current.length; j < max2; j++) {
+ FileSystem.Classpath classpath =
+ FileSystem.getClasspath(current[j].getAbsolutePath(),
+ null, false, null, null);
+ if (classpath != null) {
+ bootclasspaths.add(classpath);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return bootclasspaths;
+}
+
+/*
+ * External API
+ */
+protected ArrayList handleClasspath(ArrayList classpaths, String customEncoding) {
+ final int classpathsSize = classpaths == null ? 0 : classpaths.size();
+ if (classpathsSize != 0) {
+ String[] paths = new String[classpathsSize];
+ classpaths.toArray(paths);
+ classpaths.clear();
+ for (int i = 0; i < classpathsSize; i++) {
+ processPathEntries(DEFAULT_SIZE_CLASSPATH, classpaths, paths[i],
+ customEncoding, false, true);
+ }
+ } else {
+ // no user classpath specified.
+ classpaths = new ArrayList(DEFAULT_SIZE_CLASSPATH);
+ String classProp = System.getProperty("java.class.path"); //$NON-NLS-1$
+ if ((classProp == null) || (classProp.length() == 0)) {
+ addPendingErrors(this.bind("configure.noClasspath")); //$NON-NLS-1$
+ final Classpath classpath = FileSystem.getClasspath(System.getProperty("user.dir"), customEncoding, null);//$NON-NLS-1$
+ if (classpath != null) {
+ classpaths.add(classpath);
+ }
+ } else {
+ StringTokenizer tokenizer = new StringTokenizer(classProp, File.pathSeparator);
+ String token;
+ while (tokenizer.hasMoreTokens()) {
+ token = tokenizer.nextToken();
+ FileSystem.Classpath currentClasspath = FileSystem
+ .getClasspath(token, customEncoding, null);
+ if (currentClasspath != null) {
+ classpaths.add(currentClasspath);
+ } else if (token.length() != 0) {
+ addPendingErrors(this.bind("configure.incorrectClasspath", token));//$NON-NLS-1$
+ }
+ }
+ }
+ }
+ ArrayList result = new ArrayList();
+ HashMap knownNames = new HashMap();
+ FileSystem.ClasspathSectionProblemReporter problemReporter =
+ new FileSystem.ClasspathSectionProblemReporter() {
+ public void invalidClasspathSection(String jarFilePath) {
+ addPendingErrors(bind("configure.invalidClasspathSection", jarFilePath)); //$NON-NLS-1$
+ }
+ public void multipleClasspathSections(String jarFilePath) {
+ addPendingErrors(bind("configure.multipleClasspathSections", jarFilePath)); //$NON-NLS-1$
+ }
+ };
+ while (! classpaths.isEmpty()) {
+ Classpath current = (Classpath) classpaths.remove(0);
+ String currentPath = current.getPath();
+ if (knownNames.get(currentPath) == null) {
+ knownNames.put(currentPath, current);
+ result.add(current);
+ List linkedJars = current.fetchLinkedJars(problemReporter);
+ if (linkedJars != null) {
+ classpaths.addAll(0, linkedJars);
+ }
+ }
+ }
+ return result;
+}
+/*
+ * External API
+ */
+protected ArrayList handleEndorseddirs(ArrayList endorsedDirClasspaths) {
+ final File javaHome = getJavaHome();
+ /*
+ * Feed endorsedDirClasspath according to:
+ * - -endorseddirs first if present;
+ * - else java.endorsed.dirs if defined;
+ * - else default extensions directory for the platform. (/lib/endorsed)
+ */
+ if (endorsedDirClasspaths == null) {
+ endorsedDirClasspaths = new ArrayList(DEFAULT_SIZE_CLASSPATH);
+ String endorsedDirsStr = System.getProperty("java.endorsed.dirs"); //$NON-NLS-1$
+ if (endorsedDirsStr == null) {
+ if (javaHome != null) {
+ endorsedDirClasspaths.add(javaHome.getAbsolutePath() + "/lib/endorsed"); //$NON-NLS-1$
+ }
+ } else {
+ StringTokenizer tokenizer = new StringTokenizer(endorsedDirsStr, File.pathSeparator);
+ while (tokenizer.hasMoreTokens()) {
+ endorsedDirClasspaths.add(tokenizer.nextToken());
+ }
+ }
+ }
+
+ /*
+ * Feed extdirsClasspath with the entries found into the directories listed by
+ * extdirsNames.
+ */
+ if (endorsedDirClasspaths.size() != 0) {
+ File[] directoriesToCheck = new File[endorsedDirClasspaths.size()];
+ for (int i = 0; i < directoriesToCheck.length; i++)
+ directoriesToCheck[i] = new File((String) endorsedDirClasspaths.get(i));
+ endorsedDirClasspaths.clear();
+ File[][] endorsedDirsJars = getLibrariesFiles(directoriesToCheck);
+ if (endorsedDirsJars != null) {
+ for (int i = 0, max = endorsedDirsJars.length; i < max; i++) {
+ File[] current = endorsedDirsJars[i];
+ if (current != null) {
+ for (int j = 0, max2 = current.length; j < max2; j++) {
+ FileSystem.Classpath classpath =
+ FileSystem.getClasspath(
+ current[j].getAbsolutePath(),
+ null, null);
+ if (classpath != null) {
+ endorsedDirClasspaths.add(classpath);
+ }
+ }
+ } else if (directoriesToCheck[i].isFile()) {
+ addPendingErrors(
+ this.bind(
+ "configure.incorrectEndorsedDirsEntry", //$NON-NLS-1$
+ directoriesToCheck[i].getAbsolutePath()));
+ }
+ }
+ }
+ }
+ return endorsedDirClasspaths;
+}
+
+/*
+ * External API
+ * Handle extdirs processing
+ */
+protected ArrayList handleExtdirs(ArrayList extdirsClasspaths) {
+ final File javaHome = getJavaHome();
+
+ /*
+ * Feed extDirClasspath according to:
+ * - -extdirs first if present;
+ * - else java.ext.dirs if defined;
+ * - else default extensions directory for the platform.
+ */
+ if (extdirsClasspaths == null) {
+ extdirsClasspaths = new ArrayList(DEFAULT_SIZE_CLASSPATH);
+ String extdirsStr = System.getProperty("java.ext.dirs"); //$NON-NLS-1$
+ if (extdirsStr == null) {
+ extdirsClasspaths.add(javaHome.getAbsolutePath() + "/lib/ext"); //$NON-NLS-1$
+ } else {
+ StringTokenizer tokenizer = new StringTokenizer(extdirsStr, File.pathSeparator);
+ while (tokenizer.hasMoreTokens())
+ extdirsClasspaths.add(tokenizer.nextToken());
+ }
+ }
+
+ /*
+ * Feed extdirsClasspath with the entries found into the directories listed by
+ * extdirsNames.
+ */
+ if (extdirsClasspaths.size() != 0) {
+ File[] directoriesToCheck = new File[extdirsClasspaths.size()];
+ for (int i = 0; i < directoriesToCheck.length; i++)
+ directoriesToCheck[i] = new File((String) extdirsClasspaths.get(i));
+ extdirsClasspaths.clear();
+ File[][] extdirsJars = getLibrariesFiles(directoriesToCheck);
+ if (extdirsJars != null) {
+ for (int i = 0, max = extdirsJars.length; i < max; i++) {
+ File[] current = extdirsJars[i];
+ if (current != null) {
+ for (int j = 0, max2 = current.length; j < max2; j++) {
+ FileSystem.Classpath classpath =
+ FileSystem.getClasspath(
+ current[j].getAbsolutePath(),
+ null, null);
+ if (classpath != null) {
+ extdirsClasspaths.add(classpath);
+ }
+ }
+ } else if (directoriesToCheck[i].isFile()) {
+ addPendingErrors(this.bind(
+ "configure.incorrectExtDirsEntry", //$NON-NLS-1$
+ directoriesToCheck[i].getAbsolutePath()));
+ }
+ }
+ }
+ }
+
+ return extdirsClasspaths;
+}
+
+/*
+ * External API
+ * Handle a single warning token.
+*/
+protected void handleWarningToken(String token, boolean isEnabling) {
+ handleErrorOrWarningToken(token, isEnabling, ProblemSeverities.Warning);
+}
+protected void handleErrorToken(String token, boolean isEnabling) {
+ handleErrorOrWarningToken(token, isEnabling, ProblemSeverities.Error);
+}
+private void setSeverity(String compilerOptions, int severity, boolean isEnabling) {
+ if (isEnabling) {
+ switch(severity) {
+ case ProblemSeverities.Error :
+ this.options.put(compilerOptions, CompilerOptions.ERROR);
+ break;
+ case ProblemSeverities.Warning :
+ this.options.put(compilerOptions, CompilerOptions.WARNING);
+ break;
+ default:
+ this.options.put(compilerOptions, CompilerOptions.IGNORE);
+ }
+ } else {
+ switch(severity) {
+ case ProblemSeverities.Error :
+ String currentValue = (String) this.options.get(compilerOptions);
+ if (CompilerOptions.ERROR.equals(currentValue)) {
+ this.options.put(compilerOptions, CompilerOptions.IGNORE);
+ }
+ break;
+ case ProblemSeverities.Warning :
+ currentValue = (String) this.options.get(compilerOptions);
+ if (CompilerOptions.WARNING.equals(currentValue)) {
+ this.options.put(compilerOptions, CompilerOptions.IGNORE);
+ }
+ break;
+ default:
+ this.options.put(compilerOptions, CompilerOptions.IGNORE);
+ }
+ }
+}
+private void handleErrorOrWarningToken(String token, boolean isEnabling, int severity) {
+ if (token.length() == 0) return;
+ switch(token.charAt(0)) {
+ case 'a' :
+ if (token.equals("allDeprecation")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportDeprecation, severity, isEnabling);
+ this.options.put(
+ CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode,
+ isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+ this.options.put(
+ CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod,
+ isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+ return;
+ } else if (token.equals("allJavadoc")) { //$NON-NLS-1$
+ this.warnAllJavadocOn = this.warnJavadocOn = isEnabling;
+ setSeverity(CompilerOptions.OPTION_ReportInvalidJavadoc, severity, isEnabling);
+ setSeverity(CompilerOptions.OPTION_ReportMissingJavadocTags, severity, isEnabling);
+ setSeverity(CompilerOptions.OPTION_ReportMissingJavadocComments, severity, isEnabling);
+ return;
+ } else if (token.equals("assertIdentifier")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportAssertIdentifier, severity, isEnabling);
+ return;
+ } else if (token.equals("allDeadCode")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportDeadCode, severity, isEnabling);
+ this.options.put(
+ CompilerOptions.OPTION_ReportDeadCodeInTrivialIfStatement,
+ isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+ return;
+ } else if (token.equals("allOver-ann")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportMissingOverrideAnnotation, severity, isEnabling);
+ this.options.put(
+ CompilerOptions.OPTION_ReportMissingOverrideAnnotationForInterfaceMethodImplementation,
+ isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+ return;
+//{ObjectTeams:
+ } else if (token.equals("ambiguousbinding")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportPotentialAmbiguousPlayedby, severity, isEnabling);
+ return;
+ } else if (token.equals("ambiguouslowering")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportAmbiguousLowering, severity, isEnabling);
+ return;
+ } else if (token.equals("abstractrelevantrole")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportAbstractPotentialRelevantRole, severity, isEnabling);
+ return;
+ } else if (token.equals("adaptDeprecated")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportAdaptingDeprecated, severity, isEnabling);
+ return;
+// SH}
+ }
+ break;
+ case 'b' :
+ if (token.equals("boxing")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportAutoboxing, severity, isEnabling);
+ return;
+//{ObjectTeams:
+ } else if (token.equals("basecall")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportNotExactlyOneBasecall, severity, isEnabling);
+ return;
+ } else if (token.equals("bindingconventions")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportBindingConventions, severity, isEnabling);
+ return;
+ } else if (token.equals("bindingtosystemclass")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportWeaveIntoSystemClass, severity, isEnabling);
+ return;
+// SH}
+ }
+ break;
+ case 'c' :
+ if (token.equals("constructorName")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportMethodWithConstructorName, severity, isEnabling);
+ return;
+ } else if (token.equals("conditionAssign")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportPossibleAccidentalBooleanAssignment, severity, isEnabling);
+ return;
+ } else if (token.equals("compareIdentical")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportComparingIdentical, severity, isEnabling);
+ return;
+ } else if (token.equals("charConcat") /*|| token.equals("noImplicitStringConversion")/*backward compatible*/) {//$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportNoImplicitStringConversion, severity, isEnabling);
+ return;
+ }
+ break;
+ case 'd' :
+ if (token.equals("deprecation")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportDeprecation, severity, isEnabling);
+ this.options.put(
+ CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode,
+ CompilerOptions.DISABLED);
+ this.options.put(
+ CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod,
+ CompilerOptions.DISABLED);
+ return;
+ } else if (token.equals("dep-ann")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportMissingDeprecatedAnnotation, severity, isEnabling);
+ return;
+ } else if (token.equals("discouraged")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportDiscouragedReference, severity, isEnabling);
+ return;
+ } else if (token.equals("deadCode")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportDeadCode, severity, isEnabling);
+ this.options.put(
+ CompilerOptions.OPTION_ReportDeadCodeInTrivialIfStatement,
+ CompilerOptions.DISABLED);
+ return;
+//{ObjectTeams:
+ } else if (token.equals("decapsulation")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportDecapsulation, severity, isEnabling);
+ return;
+// SH}
+ }
+ break;
+ case 'e' :
+ if (token.equals("enumSwitch") //$NON-NLS-1$
+ || token.equals("incomplete-switch")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportIncompleteEnumSwitch, severity, isEnabling);
+ return;
+ } else if (token.equals("emptyBlock")) {//$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportUndocumentedEmptyBlock, severity, isEnabling);
+ return;
+ } else if (token.equals("enumIdentifier")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportEnumIdentifier, severity, isEnabling);
+ return;
+//{ObjectTeams:
+ } else if (token.equals("exceptioninguard")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportExceptionInGuard, severity, isEnabling);
+ return;
+// SH}
+ }
+ break;
+ case 'f' :
+ if (token.equals("fieldHiding")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportFieldHiding, severity, isEnabling);
+ return;
+ } else if (token.equals("finalBound")) {//$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportFinalParameterBound, severity, isEnabling);
+ return;
+ } else if (token.equals("finally")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportFinallyBlockNotCompletingNormally, severity, isEnabling);
+ return;
+ } else if (token.equals("forbidden")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportForbiddenReference, severity, isEnabling);
+ return;
+ } else if (token.equals("fallthrough")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportFallthroughCase, severity, isEnabling);
+ return;
+//{ObjectTeams:
+ } else if (token.equals("fragilecallin")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportFragileCallin, severity, isEnabling);
+ return;
+// SH}
+ }
+ break;
+ case 'h' :
+ if (token.equals("hiding")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportHiddenCatchBlock, severity, isEnabling);
+ setSeverity(CompilerOptions.OPTION_ReportLocalVariableHiding, severity, isEnabling);
+ setSeverity(CompilerOptions.OPTION_ReportFieldHiding, severity, isEnabling);
+ setSeverity(CompilerOptions.OPTION_ReportTypeParameterHiding, severity, isEnabling);
+ return;
+ } else if (token.equals("hashCode")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportMissingHashCodeMethod, severity, isEnabling);
+ return;
+ }
+ break;
+ case 'i' :
+ if (token.equals("indirectStatic")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportIndirectStaticAccess, severity, isEnabling);
+ return;
+ } else if (token.equals("intfNonInherited") || token.equals("interfaceNonInherited")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$
+ setSeverity(CompilerOptions.OPTION_ReportIncompatibleNonInheritedInterfaceMethod, severity, isEnabling);
+ return;
+ } else if (token.equals("intfAnnotation")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportAnnotationSuperInterface, severity, isEnabling);
+ return;
+ } else if (token.equals("intfRedundant") /*|| token.equals("redundantSuperinterface")*/) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportRedundantSuperinterface, severity, isEnabling);
+ return;
+//{ObjectTeams:
+ } else if (token.equals("inferredcallout")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportInferredCallout, severity, isEnabling);
+ return;
+// SH}
+ }
+ break;
+ case 'j' :
+ if (token.equals("javadoc")) {//$NON-NLS-1$
+ this.warnJavadocOn = isEnabling;
+ setSeverity(CompilerOptions.OPTION_ReportInvalidJavadoc, severity, isEnabling);
+ setSeverity(CompilerOptions.OPTION_ReportMissingJavadocTags, severity, isEnabling);
+ return;
+ }
+ break;
+ case 'l' :
+ if (token.equals("localHiding")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportLocalVariableHiding, severity, isEnabling);
+ return;
+ }
+ break;
+ case 'm' :
+ if (token.equals("maskedCatchBlock") || token.equals("maskedCatchBlocks")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$
+ setSeverity(CompilerOptions.OPTION_ReportHiddenCatchBlock, severity, isEnabling);
+ return;
+ }
+ break;
+ case 'n' :
+ if (token.equals("nls")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportNonExternalizedStringLiteral, severity, isEnabling);
+ return;
+ } else if (token.equals("noEffectAssign")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportNoEffectAssignment, severity, isEnabling);
+ return;
+ } else if (/*token.equals("charConcat") ||*/ token.equals("noImplicitStringConversion")/*backward compatible*/) {//$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportNoImplicitStringConversion, severity, isEnabling);
+ return;
+ } else if (token.equals("null")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportNullReference, severity, isEnabling);
+ setSeverity(CompilerOptions.OPTION_ReportPotentialNullReference, severity, isEnabling);
+ setSeverity(CompilerOptions.OPTION_ReportRedundantNullCheck, severity, isEnabling);
+ return;
+ } else if (token.equals("nullDereference")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportNullReference, severity, isEnabling);
+ if (!isEnabling) {
+ setSeverity(CompilerOptions.OPTION_ReportPotentialNullReference, ProblemSeverities.Ignore, isEnabling);
+ setSeverity(CompilerOptions.OPTION_ReportRedundantNullCheck, ProblemSeverities.Ignore, isEnabling);
+ }
+ return;
+ }
+ break;
+ case 'o' :
+ if (token.equals("over-sync") /*|| token.equals("syncOverride")*/) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportMissingSynchronizedOnInheritedMethod, severity, isEnabling);
+ return;
+ } else if (token.equals("over-ann")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportMissingOverrideAnnotation, severity, isEnabling);
+ this.options.put(
+ CompilerOptions.OPTION_ReportMissingOverrideAnnotationForInterfaceMethodImplementation,
+ CompilerOptions.DISABLED);
+ return;
+//{ObjectTeams:
+ } else if (token.equals("overridefinalrole")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportOverrideFinalRole, severity, isEnabling);
+ return;
+// SH}
+ }
+ break;
+ case 'p' :
+ if (token.equals("pkgDefaultMethod") || token.equals("packageDefaultMethod")/*backward compatible*/ ) { //$NON-NLS-1$ //$NON-NLS-2$
+ setSeverity(CompilerOptions.OPTION_ReportOverridingPackageDefaultMethod, severity, isEnabling);
+ return;
+ } else if (token.equals("paramAssign")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportParameterAssignment, severity, isEnabling);
+ return;
+ }
+ break;
+ case 'r' :
+ if (token.equals("raw")) {//$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportRawTypeReference, severity, isEnabling);
+ return;
+ } else if (/*token.equals("intfRedundant") ||*/ token.equals("redundantSuperinterface")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportRedundantSuperinterface, severity, isEnabling);
+ return;
+//{ObjectTeams:
+ } else if (token.equals("roleinstantiation")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportUnsafeRoleInstantiation, severity, isEnabling);
+ return;
+ } else if (token.equals("roletypesyntax")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportDeprecatedPathSyntax, severity, isEnabling);
+ return;
+// SH}
+ }
+ break;
+ case 's' :
+ if (token.equals("specialParamHiding")) { //$NON-NLS-1$
+ this.options.put(
+ CompilerOptions.OPTION_ReportSpecialParameterHidingField,
+ isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+ return;
+ } else if (token.equals("syntheticAccess") || token.equals("synthetic-access")) { //$NON-NLS-1$ //$NON-NLS-2$
+ setSeverity(CompilerOptions.OPTION_ReportSyntheticAccessEmulation, severity, isEnabling);
+ return;
+ } else if (token.equals("staticReceiver")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportNonStaticAccessToStatic, severity, isEnabling);
+ return;
+ } else if (/*token.equals("over-sync") ||*/ token.equals("syncOverride")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportMissingSynchronizedOnInheritedMethod, severity, isEnabling);
+ return;
+ } else if (token.equals("semicolon")) {//$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportEmptyStatement, severity, isEnabling);
+ return;
+ } else if (token.equals("serial")) {//$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportMissingSerialVersion, severity, isEnabling);
+ return;
+ } else if (token.equals("suppress")) {//$NON-NLS-1$
+ this.options.put(
+ CompilerOptions.OPTION_SuppressWarnings,
+ isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+ return;
+ } else if (token.equals("static-access")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportNonStaticAccessToStatic, severity, isEnabling);
+ setSeverity(CompilerOptions.OPTION_ReportIndirectStaticAccess, severity, isEnabling);
+ return;
+ } else if (token.equals("super")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportOverridingMethodWithoutSuperInvocation, severity, isEnabling);
+ return;
+ }
+ break;
+ case 't' :
+ if (token.startsWith("tasks")) { //$NON-NLS-1$
+ String taskTags = Util.EMPTY_STRING;
+ int start = token.indexOf('(');
+ int end = token.indexOf(')');
+ if (start >= 0 && end >= 0 && start < end){
+ taskTags = token.substring(start+1, end).trim();
+ taskTags = taskTags.replace('|',',');
+ }
+ if (taskTags.length() == 0){
+ throw new IllegalArgumentException(this.bind("configure.invalidTaskTag", token)); //$NON-NLS-1$
+ }
+ this.options.put(
+ CompilerOptions.OPTION_TaskTags,
+ isEnabling ? taskTags : Util.EMPTY_STRING);
+
+ setSeverity(CompilerOptions.OPTION_ReportTasks, severity, isEnabling);
+ return;
+ } else if (token.equals("typeHiding")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportTypeParameterHiding, severity, isEnabling);
+ return;
+ }
+ break;
+ case 'u' :
+ if (token.equals("unusedLocal") || token.equals("unusedLocals")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$
+ setSeverity(CompilerOptions.OPTION_ReportUnusedLocal, severity, isEnabling);
+ return;
+ } else if (token.equals("unusedArgument") || token.equals("unusedArguments")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$
+ setSeverity(CompilerOptions.OPTION_ReportUnusedParameter, severity, isEnabling);
+ return;
+ } else if (token.equals("unusedImport") || token.equals("unusedImports")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$
+ setSeverity(CompilerOptions.OPTION_ReportUnusedImport, severity, isEnabling);
+ return;
+ } else if (token.equals("unusedAllocation")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportUnusedObjectAllocation, severity, isEnabling);
+ return;
+ } else if (token.equals("unusedPrivate")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportUnusedPrivateMember, severity, isEnabling);
+ return;
+ } else if (token.equals("unusedLabel")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportUnusedLabel, severity, isEnabling);
+ return;
+ } else if (token.equals("uselessTypeCheck")) {//$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, severity, isEnabling);
+ return;
+ } else if (token.equals("unchecked") || token.equals("unsafe")) {//$NON-NLS-1$ //$NON-NLS-2$
+ setSeverity(CompilerOptions.OPTION_ReportUncheckedTypeOperation, severity, isEnabling);
+ return;
+ } else if (token.equals("unnecessaryElse")) {//$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportUnnecessaryElse, severity, isEnabling);
+ return;
+ } else if (token.equals("unusedThrown")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportUnusedDeclaredThrownException, severity, isEnabling);
+ return;
+ } else if (token.equals("unqualifiedField") || token.equals("unqualified-field-access")) { //$NON-NLS-1$ //$NON-NLS-2$
+ setSeverity(CompilerOptions.OPTION_ReportUnqualifiedFieldAccess, severity, isEnabling);
+ return;
+ } else if (token.equals("unused")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportUnusedLocal, severity, isEnabling);
+ setSeverity(CompilerOptions.OPTION_ReportUnusedParameter, severity, isEnabling);
+ setSeverity(CompilerOptions.OPTION_ReportUnusedImport, severity, isEnabling);
+ setSeverity(CompilerOptions.OPTION_ReportUnusedPrivateMember, severity, isEnabling);
+ setSeverity(CompilerOptions.OPTION_ReportUnusedDeclaredThrownException, severity, isEnabling);
+ setSeverity(CompilerOptions.OPTION_ReportUnusedLabel, severity, isEnabling);
+ setSeverity(CompilerOptions.OPTION_ReportUnusedTypeArgumentsForMethodInvocation, severity, isEnabling);
+ return;
+ } else if (token.equals("unusedTypeArgs")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportUnusedTypeArgumentsForMethodInvocation, severity, isEnabling);
+ return;
+ }
+ break;
+ case 'v' :
+ if (token.equals("varargsCast")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportVarargsArgumentNeedCast, severity, isEnabling);
+ return;
+ }
+ break;
+ case 'w' :
+ if (token.equals("warningToken")) {//$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportUnhandledWarningToken, severity, isEnabling);
+ setSeverity(CompilerOptions.OPTION_ReportUnusedWarningToken, severity, isEnabling);
+ return;
+ }
+ break;
+ }
+ String message = null;
+ switch(severity) {
+ case ProblemSeverities.Warning :
+ message = this.bind("configure.invalidWarning", token); //$NON-NLS-1$
+ break;
+ case ProblemSeverities.Error :
+ message = this.bind("configure.invalidError", token); //$NON-NLS-1$
+ }
+ addPendingErrors(message);
+}
+/**
+ * @deprecated - use {@link #initialize(PrintWriter, PrintWriter, boolean, Map, CompilationProgress)} instead
+ * e.g. initialize(outWriter, errWriter, systemExit, null, null)
+ */
+protected void initialize(PrintWriter outWriter, PrintWriter errWriter, boolean systemExit) {
+ this.initialize(outWriter, errWriter, systemExit, null /* options */, null /* progress */);
+}
+/**
+ * @deprecated - use {@link #initialize(PrintWriter, PrintWriter, boolean, Map, CompilationProgress)} instead
+ * e.g. initialize(outWriter, errWriter, systemExit, customDefaultOptions, null)
+ */
+protected void initialize(PrintWriter outWriter, PrintWriter errWriter, boolean systemExit, Map customDefaultOptions) {
+ this.initialize(outWriter, errWriter, systemExit, customDefaultOptions, null /* progress */);
+}
+protected void initialize(PrintWriter outWriter, PrintWriter errWriter, boolean systemExit, Map customDefaultOptions, CompilationProgress compilationProgress) {
+ this.logger = new Logger(this, outWriter, errWriter);
+ this.proceed = true;
+ this.out = outWriter;
+ this.err = errWriter;
+ this.systemExitWhenFinished = systemExit;
+ this.options = new CompilerOptions().getMap();
+
+ this.progress = compilationProgress;
+ if (customDefaultOptions != null) {
+ this.didSpecifySource = customDefaultOptions.get(CompilerOptions.OPTION_Source) != null;
+ this.didSpecifyTarget = customDefaultOptions.get(CompilerOptions.OPTION_TargetPlatform) != null;
+ for (Iterator iter = customDefaultOptions.entrySet().iterator(); iter.hasNext();) {
+ Map.Entry entry = (Map.Entry) iter.next();
+ this.options.put(entry.getKey(), entry.getValue());
+ }
+ } else {
+ this.didSpecifySource = false;
+ this.didSpecifyTarget = false;
+ }
+ this.classNames = null;
+}
+protected void initializeAnnotationProcessorManager() {
+ try {
+ Class c = Class.forName("org.eclipse.jdt.internal.compiler.apt.dispatch.BatchAnnotationProcessorManager"); //$NON-NLS-1$
+ AbstractAnnotationProcessorManager annotationManager = (AbstractAnnotationProcessorManager) c.newInstance();
+ annotationManager.configure(this, this.expandedCommandLine);
+ annotationManager.setErr(this.err);
+ annotationManager.setOut(this.out);
+ this.batchCompiler.annotationProcessorManager = annotationManager;
+ } catch (ClassNotFoundException e) {
+ // ignore
+ } catch (InstantiationException e) {
+ // should not happen
+ throw new org.eclipse.jdt.internal.compiler.problem.AbortCompilation();
+ } catch (IllegalAccessException e) {
+ // should not happen
+ throw new org.eclipse.jdt.internal.compiler.problem.AbortCompilation();
+ } catch(UnsupportedClassVersionError e) {
+ // report a warning
+ this.logger.logIncorrectVMVersionForAnnotationProcessing();
+ }
+}
+
+// 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) {
+ if (!((unitResult == null) || (unitResult.hasErrors() && !this.proceedOnError))) {
+ ClassFile[] classFiles = unitResult.getClassFiles();
+ String currentDestinationPath = null;
+ boolean generateClasspathStructure = false;
+ CompilationUnit compilationUnit =
+ (CompilationUnit) unitResult.compilationUnit;
+ if (compilationUnit.destinationPath == null) {
+ if (this.destinationPath == null) {
+ currentDestinationPath =
+ extractDestinationPathFromSourceFile(unitResult);
+ } else if (this.destinationPath != NONE) {
+ currentDestinationPath = this.destinationPath;
+ generateClasspathStructure = true;
+ } // else leave currentDestinationPath null
+ } else if (compilationUnit.destinationPath != NONE) {
+ currentDestinationPath = compilationUnit.destinationPath;
+ generateClasspathStructure = true;
+ } // else leave currentDestinationPath null
+ if (currentDestinationPath != null) {
+ for (int i = 0, fileCount = classFiles.length; i < fileCount; i++) {
+ // retrieve the key and the corresponding classfile
+ ClassFile classFile = classFiles[i];
+ char[] filename = classFile.fileName();
+ int length = filename.length;
+ char[] relativeName = new char[length + 6];
+ System.arraycopy(filename, 0, relativeName, 0, length);
+ System.arraycopy(SuffixConstants.SUFFIX_class, 0, relativeName, length, 6);
+ CharOperation.replace(relativeName, '/', File.separatorChar);
+ String relativeStringName = new String(relativeName);
+ try {
+ if (this.compilerOptions.verbose)
+ this.out.println(
+ Messages.bind(
+ Messages.compilation_write,
+ new String[] {
+ String.valueOf(this.exportedClassFilesCounter+1),
+ relativeStringName
+ }));
+ Util.writeToDisk(
+ generateClasspathStructure,
+ currentDestinationPath,
+ relativeStringName,
+ classFile);
+ this.logger.logClassFile(
+ generateClasspathStructure,
+ currentDestinationPath,
+ relativeStringName);
+ this.exportedClassFilesCounter++;
+ } catch (IOException e) {
+ this.logger.logNoClassFileCreated(currentDestinationPath, relativeStringName, e);
+ }
+ }
+ this.batchCompiler.lookupEnvironment.releaseClassFiles(classFiles);
+ }
+ }
+}
+/*
+ * Low-level API performing the actual compilation
+ */
+public void performCompilation() {
+
+//{ObjectTeams: initialize problem lists:
+ this.logger._globalProblems = new ArrayList<IProblem>();
+ this.logger._globalErrors = new ArrayList<IProblem>();
+ this.logger._globalWarnings = new ArrayList<IProblem>();
+//carp}
+
+ this.startTime = System.currentTimeMillis();
+
+ FileSystem environment = getLibraryAccess();
+ this.compilerOptions = new CompilerOptions(this.options);
+ this.compilerOptions.performMethodsFullRecovery = false;
+ this.compilerOptions.performStatementsRecovery = false;
+ this.batchCompiler =
+ new Compiler(
+ environment,
+ getHandlingPolicy(),
+ this.compilerOptions,
+ getBatchRequestor(),
+ getProblemFactory(),
+ this.out,
+ this.progress);
+//{ObjectTeams: mark as batch:
+ this.batchCompiler.isBatchCompiler = true;
+// SH}
+ this.batchCompiler.remainingIterations = this.maxRepetition-this.currentRepetition/*remaining iterations including this one*/;
+ // temporary code to allow the compiler to revert to a single thread
+ String setting = System.getProperty("jdt.compiler.useSingleThread"); //$NON-NLS-1$
+ this.batchCompiler.useSingleThread = setting != null && setting.equals("true"); //$NON-NLS-1$
+
+ if (this.compilerOptions.complianceLevel >= ClassFileConstants.JDK1_6
+ && this.compilerOptions.processAnnotations) {
+ if (checkVMVersion(ClassFileConstants.JDK1_6)) {
+ initializeAnnotationProcessorManager();
+ if (this.classNames != null) {
+ this.batchCompiler.setBinaryTypes(processClassNames(this.batchCompiler.lookupEnvironment));
+ }
+ } else {
+ // report a warning
+ this.logger.logIncorrectVMVersionForAnnotationProcessing();
+ }
+ }
+
+ // set the non-externally configurable options.
+ this.compilerOptions.verbose = this.verbose;
+ this.compilerOptions.produceReferenceInfo = this.produceRefInfo;
+ try {
+ this.logger.startLoggingSources();
+ this.batchCompiler.compile(getCompilationUnits());
+ } finally {
+ this.logger.endLoggingSources();
+ }
+
+ if (this.extraProblems != null) {
+ this.logger.loggingExtraProblems(this);
+ this.extraProblems = null;
+ }
+ if (this.compilerStats != null) {
+ this.compilerStats[this.currentRepetition] = this.batchCompiler.stats;
+ }
+ this.logger.printStats();
+
+ // cleanup
+ environment.cleanup();
+}
+public void printUsage() {
+ printUsage("misc.usage"); //$NON-NLS-1$
+}
+private void printUsage(String sectionID) {
+ this.logger.logUsage(
+ this.bind(
+ sectionID,
+ new String[] {
+ System.getProperty("path.separator"), //$NON-NLS-1$
+ this.bind("compiler.name"), //$NON-NLS-1$
+ this.bind("compiler.version"), //$NON-NLS-1$
+ this.bind("compiler.copyright") //$NON-NLS-1$
+ }));
+ this.logger.flush();
+}
+private ReferenceBinding[] processClassNames(LookupEnvironment environment) {
+ // check for .class file presence in case of apt processing
+ int length = this.classNames.length;
+ ReferenceBinding[] referenceBindings = new ReferenceBinding[length];
+ for (int i = 0; i < length; i++) {
+ String currentName = this.classNames[i];
+ char[][] compoundName = null;
+ if (currentName.indexOf('.') != -1) {
+ // consider names with '.' as fully qualified names
+ char[] typeName = currentName.toCharArray();
+ compoundName = CharOperation.splitOn('.', typeName);
+ } else {
+ compoundName = new char[][] { currentName.toCharArray() };
+ }
+ ReferenceBinding type = environment.getType(compoundName);
+ if (type != null && type.isValidBinding()) {
+ if (type.isBinaryBinding()) {
+ referenceBindings[i] = type;
+ }
+ } else {
+ throw new IllegalArgumentException(
+ this.bind("configure.invalidClassName", currentName));//$NON-NLS-1$
+ }
+ }
+ return referenceBindings;
+}
+/*
+ * External API
+ */
+public void processPathEntries(final int defaultSize, final ArrayList paths,
+ final String currentPath, String customEncoding, boolean isSourceOnly,
+ boolean rejectDestinationPathOnJars) {
+ String currentClasspathName = null;
+ String currentDestinationPath = null;
+ ArrayList currentRuleSpecs = new ArrayList(defaultSize);
+ StringTokenizer tokenizer = new StringTokenizer(currentPath,
+ File.pathSeparator + "[]", true); //$NON-NLS-1$
+ ArrayList tokens = new ArrayList();
+ while (tokenizer.hasMoreTokens()) {
+ tokens.add(tokenizer.nextToken());
+ }
+ // state machine
+ final int start = 0;
+ final int readyToClose = 1;
+ // 'path' 'path1[rule];path2'
+ final int readyToCloseEndingWithRules = 2;
+ // 'path[rule]' 'path1;path2[rule]'
+ final int readyToCloseOrOtherEntry = 3;
+ // 'path[rule];' 'path;' 'path1;path2;'
+ final int rulesNeedAnotherRule = 4;
+ // 'path[rule1;'
+ final int rulesStart = 5;
+ // 'path[' 'path1;path2['
+ final int rulesReadyToClose = 6;
+ // 'path[rule' 'path[rule1;rule2'
+ final int destinationPathReadyToClose = 7;
+ // 'path[-d bin'
+ final int readyToCloseEndingWithDestinationPath = 8;
+ // 'path[-d bin]' 'path[rule][-d bin]'
+ final int destinationPathStart = 9;
+ // 'path[rule]['
+ final int bracketOpened = 10;
+ // '.*[.*'
+ final int bracketClosed = 11;
+ // '.*([.*])+'
+
+ final int error = 99;
+ int state = start;
+ String token = null;
+ int cursor = 0, tokensNb = tokens.size(), bracket = -1;
+ while (cursor < tokensNb && state != error) {
+ token = (String) tokens.get(cursor++);
+ if (token.equals(File.pathSeparator)) {
+ switch (state) {
+ case start:
+ case readyToCloseOrOtherEntry:
+ case bracketOpened:
+ break;
+ case readyToClose:
+ case readyToCloseEndingWithRules:
+ case readyToCloseEndingWithDestinationPath:
+ state = readyToCloseOrOtherEntry;
+ addNewEntry(paths, currentClasspathName, currentRuleSpecs,
+ customEncoding, currentDestinationPath, isSourceOnly,
+ rejectDestinationPathOnJars);
+ currentRuleSpecs.clear();
+ break;
+ case rulesReadyToClose:
+ state = rulesNeedAnotherRule;
+ break;
+ case destinationPathReadyToClose:
+ throw new IllegalArgumentException(
+ this.bind("configure.incorrectDestinationPathEntry", //$NON-NLS-1$
+ currentPath));
+ case bracketClosed:
+ cursor = bracket + 1;
+ state = rulesStart;
+ break;
+ default:
+ state = error;
+ }
+ } else if (token.equals("[")) { //$NON-NLS-1$
+ switch (state) {
+ case start:
+ currentClasspathName = ""; //$NON-NLS-1$
+ //$FALL-THROUGH$
+ case readyToClose:
+ bracket = cursor - 1;
+ //$FALL-THROUGH$
+ case bracketClosed:
+ state = bracketOpened;
+ break;
+ case readyToCloseEndingWithRules:
+ state = destinationPathStart;
+ break;
+ case readyToCloseEndingWithDestinationPath:
+ state = rulesStart;
+ break;
+ case bracketOpened:
+ default:
+ state = error;
+ }
+ } else if (token.equals("]")) { //$NON-NLS-1$
+ switch (state) {
+ case rulesReadyToClose:
+ state = readyToCloseEndingWithRules;
+ break;
+ case destinationPathReadyToClose:
+ state = readyToCloseEndingWithDestinationPath;
+ break;
+ case bracketOpened:
+ state = bracketClosed;
+ break;
+ case bracketClosed:
+ default:
+ state = error;
+ }
+ } else {
+ // regular word
+ switch (state) {
+ case start:
+ case readyToCloseOrOtherEntry:
+ state = readyToClose;
+ currentClasspathName = token;
+ break;
+ case rulesStart:
+ if (token.startsWith("-d ")) { //$NON-NLS-1$
+ if (currentDestinationPath != null) {
+ throw new IllegalArgumentException(
+ this.bind("configure.duplicateDestinationPathEntry", //$NON-NLS-1$
+ currentPath));
+ }
+ currentDestinationPath = token.substring(3).trim();
+ state = destinationPathReadyToClose;
+ break;
+ } // else we proceed with a rule
+ //$FALL-THROUGH$
+ case rulesNeedAnotherRule:
+ if (currentDestinationPath != null) {
+ throw new IllegalArgumentException(
+ this.bind("configure.accessRuleAfterDestinationPath", //$NON-NLS-1$
+ currentPath));
+ }
+ state = rulesReadyToClose;
+ currentRuleSpecs.add(token);
+ break;
+ case destinationPathStart:
+ if (!token.startsWith("-d ")) { //$NON-NLS-1$
+ state = error;
+ } else {
+ currentDestinationPath = token.substring(3).trim();
+ state = destinationPathReadyToClose;
+ }
+ break;
+ case bracketClosed:
+ for (int i = bracket; i < cursor ; i++) {
+ currentClasspathName += (String) tokens.get(i);
+ }
+ state = readyToClose;
+ break;
+ case bracketOpened:
+ break;
+ default:
+ state = error;
+ }
+ }
+ if (state == bracketClosed && cursor == tokensNb) {
+ cursor = bracket + 1;
+ state = rulesStart;
+ }
+ }
+ switch(state) {
+ case readyToCloseOrOtherEntry:
+ break;
+ case readyToClose:
+ case readyToCloseEndingWithRules:
+ case readyToCloseEndingWithDestinationPath:
+ addNewEntry(paths, currentClasspathName, currentRuleSpecs,
+ customEncoding, currentDestinationPath, isSourceOnly,
+ rejectDestinationPathOnJars);
+ break;
+ case bracketOpened:
+ case bracketClosed:
+ default :
+ // we go on anyway
+ if (currentPath.length() != 0) {
+ addPendingErrors(this.bind("configure.incorrectClasspath", currentPath));//$NON-NLS-1$
+ }
+ }
+}
+
+private int processPaths(String[] args, int index, String currentArg, ArrayList paths) {
+ int localIndex = index;
+ int count = 0;
+ for (int i = 0, max = currentArg.length(); i < max; i++) {
+ switch(currentArg.charAt(i)) {
+ case '[' :
+ count++;
+ break;
+ case ']' :
+ count--;
+ break;
+ }
+ }
+ if (count == 0) {
+ paths.add(currentArg);
+ } else if (count > 1) {
+ throw new IllegalArgumentException(
+ this.bind("configure.unexpectedBracket", //$NON-NLS-1$
+ currentArg));
+ } else {
+ StringBuffer currentPath = new StringBuffer(currentArg);
+ while (true) {
+ if (localIndex >= args.length) {
+ throw new IllegalArgumentException(
+ this.bind("configure.unexpectedBracket", //$NON-NLS-1$
+ currentArg));
+ }
+ localIndex++;
+ String nextArg = args[localIndex];
+ for (int i = 0, max = nextArg.length(); i < max; i++) {
+ switch(nextArg.charAt(i)) {
+ case '[' :
+ if (count > 1) {
+ throw new IllegalArgumentException(
+ this.bind("configure.unexpectedBracket", //$NON-NLS-1$
+ nextArg));
+ }
+ count++;
+ break;
+ case ']' :
+ count--;
+ break;
+ }
+ }
+ if (count == 0) {
+ currentPath.append(' ');
+ currentPath.append(nextArg);
+ paths.add(currentPath.toString());
+ return localIndex - index;
+ } else if (count < 0) {
+ throw new IllegalArgumentException(
+ this.bind("configure.unexpectedBracket", //$NON-NLS-1$
+ nextArg));
+ } else {
+ currentPath.append(' ');
+ currentPath.append(nextArg);
+ }
+ }
+
+ }
+ return localIndex - index;
+}
+private int processPaths(String[] args, int index, String currentArg, String[] paths) {
+ int localIndex = index;
+ int count = 0;
+ for (int i = 0, max = currentArg.length(); i < max; i++) {
+ switch(currentArg.charAt(i)) {
+ case '[' :
+ count++;
+ break;
+ case ']' :
+ count--;
+ break;
+ }
+ }
+ if (count == 0) {
+ paths[0] = currentArg;
+ } else {
+ StringBuffer currentPath = new StringBuffer(currentArg);
+ while (true) {
+ localIndex++;
+ if (localIndex >= args.length) {
+ throw new IllegalArgumentException(
+ this.bind("configure.unexpectedBracket", //$NON-NLS-1$
+ currentArg));
+ }
+ String nextArg = args[localIndex];
+ for (int i = 0, max = nextArg.length(); i < max; i++) {
+ switch(nextArg.charAt(i)) {
+ case '[' :
+ if (count > 1) {
+ throw new IllegalArgumentException(
+ this.bind("configure.unexpectedBracket", //$NON-NLS-1$
+ currentArg));
+ }
+ count++;
+ break;
+ case ']' :
+ count--;
+ break;
+ }
+ }
+ if (count == 0) {
+ currentPath.append(' ');
+ currentPath.append(nextArg);
+ paths[0] = currentPath.toString();
+ return localIndex - index;
+ } else if (count < 0) {
+ throw new IllegalArgumentException(
+ this.bind("configure.unexpectedBracket", //$NON-NLS-1$
+ currentArg));
+ } else {
+ currentPath.append(' ');
+ currentPath.append(nextArg);
+ }
+ }
+
+ }
+ return localIndex - index;
+}
+/**
+ * Creates a NLS catalog for the given locale.
+ */
+public void relocalize() {
+ relocalize(Locale.getDefault());
+}
+
+private void relocalize(Locale locale) {
+ this.compilerLocale = locale;
+ try {
+ this.bundle = ResourceBundleFactory.getBundle(locale);
+ } catch(MissingResourceException e) {
+ System.out.println("Missing resource : " + Main.bundleName.replace('.', '/') + ".properties for locale " + locale); //$NON-NLS-1$//$NON-NLS-2$
+ throw e;
+ }
+}
+/*
+ * External API
+ */
+public void setDestinationPath(String dest) {
+ this.destinationPath = dest;
+}
+/*
+ * External API
+ */
+public void setLocale(Locale locale) {
+ relocalize(locale);
+}
+/*
+ * External API
+ */
+protected void setPaths(ArrayList bootclasspaths,
+ String sourcepathClasspathArg,
+ ArrayList sourcepathClasspaths,
+ ArrayList classpaths,
+ ArrayList extdirsClasspaths,
+ ArrayList endorsedDirClasspaths,
+ String customEncoding) {
+
+ // process bootclasspath, classpath and sourcepaths
+ bootclasspaths = handleBootclasspath(bootclasspaths, customEncoding);
+
+ classpaths = handleClasspath(classpaths, customEncoding);
+
+ if (sourcepathClasspathArg != null) {
+ processPathEntries(DEFAULT_SIZE_CLASSPATH, sourcepathClasspaths,
+ sourcepathClasspathArg, customEncoding, true, false);
+ }
+
+ /*
+ * Feed endorsedDirClasspath according to:
+ * - -extdirs first if present;
+ * - else java.ext.dirs if defined;
+ * - else default extensions directory for the platform.
+ */
+ extdirsClasspaths = handleExtdirs(extdirsClasspaths);
+
+ endorsedDirClasspaths = handleEndorseddirs(endorsedDirClasspaths);
+
+ /*
+ * Concatenate classpath entries
+ * We put the bootclasspath at the beginning of the classpath
+ * entries, followed by the extension libraries, followed by
+ * the sourcepath followed by the classpath. All classpath
+ * entries are searched for both sources and binaries except
+ * the sourcepath entries which are searched for sources only.
+ */
+ bootclasspaths.addAll(endorsedDirClasspaths);
+ bootclasspaths.addAll(extdirsClasspaths);
+ bootclasspaths.addAll(sourcepathClasspaths);
+ bootclasspaths.addAll(classpaths);
+ classpaths = bootclasspaths;
+ classpaths = FileSystem.ClasspathNormalizer.normalize(classpaths);
+ this.checkedClasspaths = new FileSystem.Classpath[classpaths.size()];
+ classpaths.toArray(this.checkedClasspaths);
+ this.logger.logClasspath(this.checkedClasspaths);
+}
+protected void validateOptions(boolean didSpecifyCompliance) {
+ if (didSpecifyCompliance) {
+ Object version = this.options.get(CompilerOptions.OPTION_Compliance);
+ if (CompilerOptions.VERSION_1_3.equals(version)) {
+ if (!this.didSpecifySource) this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3);
+ if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_1);
+ } else if (CompilerOptions.VERSION_1_4.equals(version)) {
+ if (this.didSpecifySource) {
+ Object source = this.options.get(CompilerOptions.OPTION_Source);
+ if (CompilerOptions.VERSION_1_3.equals(source)) {
+ if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_2);
+ } else if (CompilerOptions.VERSION_1_4.equals(source)) {
+ if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
+ }
+ } else {
+ this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3);
+ if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_2);
+ }
+ } else if (CompilerOptions.VERSION_1_5.equals(version)) {
+ if (this.didSpecifySource) {
+ Object source = this.options.get(CompilerOptions.OPTION_Source);
+ if (CompilerOptions.VERSION_1_3.equals(source)
+ || CompilerOptions.VERSION_1_4.equals(source)) {
+ if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
+ } else if (CompilerOptions.VERSION_1_5.equals(source)) {
+ if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5);
+ }
+ } else {
+ this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5);
+ if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5);
+ }
+ } else if (CompilerOptions.VERSION_1_6.equals(version)) {
+ if (this.didSpecifySource) {
+ Object source = this.options.get(CompilerOptions.OPTION_Source);
+ if (CompilerOptions.VERSION_1_3.equals(source)
+ || CompilerOptions.VERSION_1_4.equals(source)) {
+ if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
+ } else if (CompilerOptions.VERSION_1_5.equals(source)
+ || CompilerOptions.VERSION_1_6.equals(source)) {
+ if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
+ }
+ } else {
+ this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_6);
+ if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
+ }
+ } else if (CompilerOptions.VERSION_1_7.equals(version)) {
+ if (this.didSpecifySource) {
+ Object source = this.options.get(CompilerOptions.OPTION_Source);
+ if (CompilerOptions.VERSION_1_3.equals(source)
+ || CompilerOptions.VERSION_1_4.equals(source)) {
+ if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
+ } else if (CompilerOptions.VERSION_1_5.equals(source)
+ || CompilerOptions.VERSION_1_6.equals(source)) {
+ if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
+ } else if (CompilerOptions.VERSION_1_7.equals(source)) {
+ if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7);
+ }
+ } else {
+ this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_7);
+ if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7);
+ }
+ }
+ } else if (this.didSpecifySource) {
+ Object version = this.options.get(CompilerOptions.OPTION_Source);
+ // default is source 1.3 target 1.2 and compliance 1.4
+ if (CompilerOptions.VERSION_1_4.equals(version)) {
+ if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_4);
+ if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
+ } else if (CompilerOptions.VERSION_1_5.equals(version)) {
+ if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_5);
+ if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5);
+ } else if (CompilerOptions.VERSION_1_6.equals(version)) {
+ if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_6);
+ if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
+ } else if (CompilerOptions.VERSION_1_7.equals(version)) {
+ if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_7);
+ if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7);
+ }
+ }
+
+ final Object sourceVersion = this.options.get(CompilerOptions.OPTION_Source);
+ final Object compliance = this.options.get(CompilerOptions.OPTION_Compliance);
+ if (sourceVersion.equals(CompilerOptions.VERSION_1_7)
+ && CompilerOptions.versionToJdkLevel(compliance) < ClassFileConstants.JDK1_7) {
+ // compliance must be 1.7 if source is 1.7
+ throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForSource", (String)this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_1_7)); //$NON-NLS-1$
+ } else if (sourceVersion.equals(CompilerOptions.VERSION_1_6)
+ && CompilerOptions.versionToJdkLevel(compliance) < ClassFileConstants.JDK1_6) {
+ // compliance must be 1.6 if source is 1.6
+ throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForSource", (String)this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_1_6)); //$NON-NLS-1$
+ } else if (sourceVersion.equals(CompilerOptions.VERSION_1_5)
+ && CompilerOptions.versionToJdkLevel(compliance) < ClassFileConstants.JDK1_5) {
+ // compliance must be 1.5 if source is 1.5
+ throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForSource", (String)this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_1_5)); //$NON-NLS-1$
+ } else if (sourceVersion.equals(CompilerOptions.VERSION_1_4)
+ && CompilerOptions.versionToJdkLevel(compliance) < ClassFileConstants.JDK1_4) {
+ // compliance must be 1.4 if source is 1.4
+ throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForSource", (String)this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_1_4)); //$NON-NLS-1$
+ }
+
+ // check and set compliance/source/target compatibilities
+ if (this.didSpecifyTarget) {
+ final Object targetVersion = this.options.get(CompilerOptions.OPTION_TargetPlatform);
+ // tolerate jsr14 target
+ if (CompilerOptions.VERSION_JSR14.equals(targetVersion)) {
+ // expecting source >= 1.5
+ if (CompilerOptions.versionToJdkLevel(sourceVersion) < ClassFileConstants.JDK1_5) {
+ throw new IllegalArgumentException(this.bind("configure.incompatibleTargetForGenericSource", (String) targetVersion, (String) sourceVersion)); //$NON-NLS-1$
+ }
+ } else if (CompilerOptions.VERSION_CLDC1_1.equals(targetVersion)) {
+ if (this.didSpecifySource && CompilerOptions.versionToJdkLevel(sourceVersion) >= ClassFileConstants.JDK1_4) {
+ throw new IllegalArgumentException(this.bind("configure.incompatibleSourceForCldcTarget", (String) targetVersion, (String) sourceVersion)); //$NON-NLS-1$
+ }
+ if (CompilerOptions.versionToJdkLevel(compliance) >= ClassFileConstants.JDK1_5) {
+ throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForCldcTarget", (String) targetVersion, (String) sourceVersion)); //$NON-NLS-1$
+ }
+ } else {
+ // target must be 1.7 if source is 1.7
+ if (CompilerOptions.versionToJdkLevel(sourceVersion) >= ClassFileConstants.JDK1_7
+ && CompilerOptions.versionToJdkLevel(targetVersion) < ClassFileConstants.JDK1_7){
+ throw new IllegalArgumentException(this.bind("configure.incompatibleTargetForSource", (String) targetVersion, CompilerOptions.VERSION_1_7)); //$NON-NLS-1$
+ }
+ // target must be 1.6 if source is 1.6
+ if (CompilerOptions.versionToJdkLevel(sourceVersion) >= ClassFileConstants.JDK1_6
+ && CompilerOptions.versionToJdkLevel(targetVersion) < ClassFileConstants.JDK1_6){
+ throw new IllegalArgumentException(this.bind("configure.incompatibleTargetForSource", (String) targetVersion, CompilerOptions.VERSION_1_6)); //$NON-NLS-1$
+ }
+ // target must be 1.5 if source is 1.5
+ if (CompilerOptions.versionToJdkLevel(sourceVersion) >= ClassFileConstants.JDK1_5
+ && CompilerOptions.versionToJdkLevel(targetVersion) < ClassFileConstants.JDK1_5){
+ throw new IllegalArgumentException(this.bind("configure.incompatibleTargetForSource", (String) targetVersion, CompilerOptions.VERSION_1_5)); //$NON-NLS-1$
+ }
+ // target must be 1.4 if source is 1.4
+ if (CompilerOptions.versionToJdkLevel(sourceVersion) >= ClassFileConstants.JDK1_4
+ && CompilerOptions.versionToJdkLevel(targetVersion) < ClassFileConstants.JDK1_4){
+ throw new IllegalArgumentException(this.bind("configure.incompatibleTargetForSource", (String) targetVersion, CompilerOptions.VERSION_1_4)); //$NON-NLS-1$
+ }
+ // target cannot be greater than compliance level
+ if (CompilerOptions.versionToJdkLevel(compliance) < CompilerOptions.versionToJdkLevel(targetVersion)){
+ throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForTarget", (String)this.options.get(CompilerOptions.OPTION_Compliance), (String) targetVersion)); //$NON-NLS-1$
+ }
+ }
+ }
+}
+}
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
new file mode 100644
index 0000000..c80bd5f
--- /dev/null
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
@@ -0,0 +1,353 @@
+###############################################################################
+# Copyright (c) 2000, 2010 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
+# Benjamin Muskalla - Contribution for bug 239066
+# Fraunhofer FIRST - extended API and implementation
+# Technical University Berlin - extended API and implementation
+###############################################################################
+### JavaBatchCompiler messages.
+
+### compiler
+#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.A32, 3.6.0 M5
+compiler.copyright = Copyright IBM Corp 2000, 2010. All rights reserved.
+
+###{ObjectTeams:
+otdtc.name = Extension for Object Teams
+otdtc.version = 1.4.0 M3 $Revision: 23389 $ $LastChangedDate: 2010-01-30 19:52:27 +0100 (Sat, 30 Jan 2010) $
+otdtc.copyright = Copyright by the TOPPrax consortium, 2004, 2010.
+### SH}
+### progress
+progress.compiling = Compiling
+
+### compile
+compile.repetition = [repetition {0}/{1}]
+compile.instantTime = [compiled {0} lines in {1} ms: {2} lines/s]
+compile.detailedTime = [parse: {0} ms ({1}%), resolve: {2} ms ({3}%), analyze: {4} ms ({5}%), generate: {6} ms ({7}%) ]
+compile.ioTime = [i/o: read: {0} ms ({1}%), write: {2} ms ({3}%)]
+compile.averageTime = [average, excluding min-max {0} lines in {1} ms: {2} lines/s]
+compile.totalTime = [total compilation time: {0}]
+compile.oneProblem = 1 problem ({0})
+compile.severalProblemsErrorsOrWarnings = {0} problems ({1})
+compile.severalProblemsErrorsAndWarnings = {0} problems ({1}, {2})
+compile.oneError = 1 error
+compile.severalErrors = {0} errors
+compile.oneWarning = 1 warning
+compile.severalWarnings = {0} warnings
+compile.oneClassFileGenerated = [1 .class file generated]
+compile.severalClassFilesGenerated = [{0} .class files generated]
+
+### configure
+configure.requiresJDK1.2orAbove = Need to use a JVM >= 1.2
+configure.duplicateLog = duplicate log specification: {0}
+configure.duplicateRepeat = duplicate repeat specification: {0}
+configure.duplicateMaxProblems = duplicate max problems specification: {0}
+configure.duplicateCompliance = duplicate compliance setting specification: {0}
+configure.duplicateSource = duplicate source compliance setting specification: {0}
+configure.duplicateTarget = duplicate target compliance setting specification: {0}
+configure.source = source level should be comprised in between ''1.3'' and ''1.6'' (or ''5'', ''5.0'', ..., ''7'' or ''7.0''): {0}
+configure.duplicateOutputPath = duplicate output path specification: {0}
+configure.duplicateBootClasspath = duplicate bootclasspath specification: {0}
+configure.duplicateExtDirs = duplicate extdirs specification: {0}
+configure.duplicateSourcepath = duplicate sourcepath specification: {0}
+configure.invalidDebugOption = invalid debug option: {0}
+configure.invalidWarningConfiguration = invalid warning configuration: ''{0}''
+configure.invalidWarning = invalid warning token: ''{0}''. Ignoring warning and compiling
+configure.invalidWarningOption = invalid warning option: ''{0}''. Must specify a warning token
+configure.targetJDK = target level should be comprised in between ''1.1'' and ''1.7'' (or ''5'', ''5.0'', ..., ''7'' or ''7.0'') or cldc1.1: {0}
+configure.incompatibleTargetForSource = Target level ''{0}'' is incompatible with source level ''{1}''. A target level ''{1}'' or better is required
+configure.incompatibleTargetForGenericSource = Target level ''{0}'' is incompatible with source level ''{1}''. A source level ''1.5'' or better is required
+configure.incompatibleComplianceForSource = Compliance level ''{0}'' is incompatible with source level ''{1}''. A compliance level ''{1}'' or better is required
+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.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}
+configure.noClasspath = no classpath defined, using default directory instead
+configure.incorrectClasspath = incorrect classpath: {0}
+configure.invalidexpansionargumentname = expansion argument file {0} does not exist or cannot be read
+configure.cannotOpenLog = cannot open .log file: {0}
+configure.cannotOpenLogInvalidEncoding = cannot open .log file: {0}; because UTF-8 is not supported
+configure.unexpectedCustomEncoding = unexpected custom encoding specification: {0}[{1}]
+configure.unsupportedEncoding = unsupported encoding format: {0}
+configure.duplicateDefaultEncoding = duplicate default encoding format specification: {0}
+configure.invalidTaskTag ={0} is an invalid task tag
+configure.incorrectExtDirsEntry = incorrect ext dir entry; {0} must be a directory
+configure.incorrectEndorsedDirsEntry = incorrect endorsed dir entry; {0} must be a directory
+configure.duplicateEndorsedDirs = duplicate endorseddirs specification: {0}
+configure.incorrectDestinationPathEntry = incorrect destination path entry: {0}
+configure.unexpectedBracket = unexpected bracket: {0}
+configure.unexpectedDestinationPathEntry = unexpected destination path entry in {0} option
+configure.unexpectedDestinationPathEntryFile = unexpected destination path entry for file: {0}
+configure.accessRuleAfterDestinationPath = access rules cannot follow destination path entries: {0}
+configure.duplicateDestinationPathEntry = duplicate destination path entry in {0} option
+configure.invalidClassName = invalid class name: {0}
+configure.incorrectVMVersionforAPT = Annotation processing got disabled, since it requires a 1.6 compliant JVM
+configure.incompatibleSourceForCldcTarget=Target level ''{0}'' is incompatible with source level ''{1}''. A source level ''1.3'' or lower is required
+configure.incompatibleComplianceForCldcTarget=Target level ''{0}'' is incompatible with compliance level ''{1}''. A compliance level ''1.4''or lower is required
+configure.invalidClasspathSection = invalid Class-Path header in manifest of jar file: {0}
+configure.multipleClasspathSections = multiple Class-Path headers in manifest of jar file: {0}
+
+### requestor
+requestor.error = {0}. ERROR in {1}
+requestor.warning = {0}. WARNING in {1}
+requestor.notRetrieveErrorMessage = Cannot retrieve the error message for {0}
+requestor.noFileNameSpecified = (original file name is not available)
+
+### EMACS STYLE
+output.emacs.error=error
+output.emacs.warning=warning
+
+### unit
+unit.more = File {0} is specified more than once
+unit.missing = File {0} is missing
+
+### output
+output.noClassFileCreated = No .class file created for file {1} in {0} because of an IOException: {2}
+
+### miscellaneous
+### {ObjectTeams: one for testing the other for -version command
+misc.version.orig = {0} {1}, {2}
+misc.version = {0} {1}, {2}\n{3}, {4}, {5}
+### SH}
+misc.usage = {1} {2}\n\
+{3}\n\
+\ \n\
+\ Usage: <options> <source files | directories>\n\
+\ If directories are specified, then their source contents are compiled.\n\
+\ Possible options are listed below. Options enabled by default are prefixed\n\
+\ with ''+''.\n\
+\ \n\
+\ Classpath options:\n\
+\ -cp -classpath <directories and ZIP archives separated by {0}>\n\
+\ specify location for application classes and sources.\n\
+\ Each directory or file can specify access rules for\n\
+\ types between ''['' and '']'' (e.g. [-X] to forbid\n\
+\ access to type X, [~X] to discourage access to type X,\n\
+\ [+p/X{0}-p/*] to forbid access to all types in package p\n\
+\ but allow access to p/X)\n\
+\ -bootclasspath <directories and ZIP archives separated by {0}>\n\
+\ specify location for system classes. Each directory or\n\
+\ file can specify access rules for types between ''[''\n\
+\ and '']''\n\
+\ -sourcepath <directories and ZIP archives separated by {0}>\n\
+\ specify location for application sources. Each directory\n\
+\ or file can specify access rules for types between ''[''\n\
+\ and '']''. Each directory can further specify a specific\n\
+\ destination directory using a ''-d'' option between ''[''\n\
+\ and '']''; this overrides the general ''-d'' option.\n\
+\ .class files created from source files contained in a\n\
+\ jar file are put in the user.dir folder in case no\n\
+\ general ''-d'' option is specified. ZIP archives cannot\n\
+\ override the general ''-d'' option\n\
+\ -extdirs <directories separated by {0}>\n\
+\ specify location for extension ZIP archives\n\
+\ -endorseddirs <directories separated by {0}>\n\
+\ specify location for endorsed ZIP archives\n\
+\ -d <dir> destination directory (if omitted, no directory is\n\
+\ created); this option can be overridden per source\n\
+\ directory\n\
+\ -d none generate no .class files\n\
+\ -encoding <enc> specify custom encoding for all sources. Each\n\
+\ file/directory can override it when suffixed with\n\
+\ ''[''<enc>'']'' (e.g. X.java[utf8])\n\
+\ \n\
+\ Compliance options:\n\
+\ -1.3 use 1.3 compliance (-source 1.3 -target 1.1)\n\
+\ -1.4 + use 1.4 compliance (-source 1.3 -target 1.2)\n\
+\ -1.5 -5 -5.0 use 1.5 compliance (-source 1.5 -target 1.5)\n\
+\ -1.6 -6 -6.0 use 1.6 compliance (-source 1.6 -target 1.6)\n\
+\ -1.7 -7 -7.0 use 1.7 compliance (-source 1.7 -target 1.7)\n\
+\ -source <version> set source level: 1.3 to 1.7 (or 5, 5.0, etc)\n\
+\ -target <version> set classfile target: 1.1 to 1.7 (or 5, 5.0, etc)\n\
+\ cldc1.1 can also be used to generate the StackMap\n\
+\ attribute\n\
+\ \n\
+\ Warning options:\n\
+\ -deprecation + deprecation outside deprecated code (equivalent to\n\
+\ -warn:+deprecation)\n\
+\ -nowarn -warn:none disable all warnings\n\
+\ -?:warn -help:warn display advanced warning options\n\
+\ \n\
+\ Error options:\n\
+\ -err:<warnings separated by ,> convert exactly the listed warnings\n\
+\ to be reported as errors\n\
+\ -err:+<warnings separated by ,> enable additional warnings to be\n\
+\ reported as errors\n\
+\ -err:-<warnings separated by ,> disable specific warnings to be\n\
+\ reported as errors\n\
+\ \n\
+\ Debug options:\n\
+\ -g[:lines,vars,source] custom debug info\n\
+\ -g:lines,source + both lines table and source debug info\n\
+\ -g all debug info\n\
+\ -g:none no debug info\n\
+\ -preserveAllLocals preserve unused local vars for debug purpose\n\
+\ \n\
+\ Annotation processing options:\n\
+\ These options are meaningful only in a 1.6 environment.\n\
+\ -Akey[=value] options that are passed to annotation processors\n\
+\ -processorpath <directories and ZIP archives separated by {0}>\n\
+\ specify locations where to find annotation processors.\n\
+\ If this option is not used, the classpath will be\n\
+\ searched for processors\n\
+\ -processor <class1[,class2,...]>\n\
+\ qualified names of the annotation processors to run.\n\
+\ This bypasses the default annotation discovery process\n\
+\ -proc:only run annotation processors, but do not compile\n\
+\ -proc:none perform compilation but do not run annotation\n\
+\ processors\n\
+\ -s <dir> destination directory for generated source files\n\
+\ -XprintProcessorInfo print information about which annotations and elements\n\
+\ a processor is asked to process\n\
+\ -XprintRounds print information about annotation processing rounds\n\
+\ -classNames <className1[,className2,...]>\n\
+\ qualified names of binary classes to process\n\
+\ \n\
+\ Advanced options:\n\
+\ @<file> read command line arguments from file\n\
+\ -maxProblems <n> max number of problems per compilation unit (100 by\n\
+\ default)\n\
+\ -log <file> log to a file. If the file extension is ''.xml'', then\n\
+\ the log will be a xml file.\n\
+\ -proceedOnError[:Fatal]\n\
+\ do not stop at first error, dumping class files with\n\
+\ problem methods\n\
+\ With ":Fatal", all optional errors are treated as fatal\n\
+\ -verbose enable verbose output\n\
+\ -referenceInfo compute reference info\n\
+\ -progress show progress (only in -log mode)\n\
+\ -time display speed information \n\
+\ -noExit do not call System.exit(n) at end of compilation (n==0\n\
+\ if no error)\n\
+\ -repeat <n> repeat compilation process <n> times for perf analysis\n\
+\ -inlineJSR inline JSR bytecode (implicit if target >= 1.5)\n\
+\ -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\
+\ \n\
+\ -? -help print this help message\n\
+\ -v -version print compiler version\n\
+\ -showversion print compiler version and continue\n\
+\ \n\
+\ Ignored options:\n\
+\ -J<option> pass option to virtual machine (ignored)\n\
+\ -X<option> specify non-standard option (ignored\n\
+\ except for listed -X options)\n\
+\ -X print non-standard options and exit (ignored)\n\
+\ -O optimize for execution time (ignored)\n
+##{ObjectTeams: OT-warning tokens added
+misc.usage.warn = {1} {2}\n\
+{3}\n\
+\ \n\
+\ Warning options:\n\
+\ -deprecation + deprecation outside deprecated code\n\
+\ -nowarn -warn:none disable all warnings\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\
+\ abstractrelevantrole + abstract relevant role (OTJLD 2.5(b))\n\
+\ adaptDeprecated + adapting a deprecated type/method\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\
+\ ambiguousbinding + ambiguous role-base bindings (OTJLD 2.3.4(a))\n\
+\ ambiguouslowering + ambiguous lowering or upcast (OTJLD 2.2(f))\n\
+\ assertIdentifier + ''assert'' used as identifier\n\
+\ basecall + base call not issued exactly once on each path\n\
+\ (OTJLD 4.3(b,c))\n\
+\ bindingconventions + discouraged use of import / import base\n\
+\ (OTJLD 2.1.2(d))\n\
+\ bindingtosystemclass + trying to bind a role to a system class\n\
+\ boxing autoboxing conversion\n\
+\ charConcat + char[] in String concat\n\
+\ compareIdentical + comparing identical expressions\n\
+\ conditionAssign possible accidental boolean assignment\n\
+\ constructorName + method with constructor name\n\
+\ dangerouscallin + dangerous callin binding (hashCode or equals)\n\
+\ deadCode + dead code excluding trivial if (DEBUG) check\n\
+\ decapsulation + overriding access restrictions of a base class\n\
+\ (OTJLD 3.4)\n\
+\ dep-ann missing @Deprecated annotation\n\
+\ deprecation + deprecation outside deprecated code\n\
+\ discouraged + use of types matching a discouraged access rule\n\
+\ emptyBlock undocumented empty block\n\
+\ enumIdentifier ''enum'' used as identifier\n\
+\ enumSwitch incomplete enum switch\n\
+\ exceptioninguard + guard predicate throwing checked exception\n\
+\ fallthrough possible fall-through case\n\
+\ fieldHiding field hiding another variable\n\
+\ finalBound type parameter with final bound\n\
+\ finally + finally block not completing normally\n\
+\ forbidden + use of types matching a forbidden access rule\n\
+\ fragilecallin + replace callin not providing expected result\n\
+\ (OTJLD 4.3(e))\n\
+\ hashCode missing hashCode() method when overriding equals()\n\
+\ hiding macro for fieldHiding, localHiding, typeHiding and\n\
+\ maskedCatchBlock\n\
+\ incomplete-switch same as enumSwitch\n\
+\ indirectStatic indirect reference to static member\n\
+\ inferredcallout + a callout binding has to be inferred (OTJLD 3.1(j))\n\
+\ intfAnnotation + annotation type used as super interface\n\
+\ intfNonInherited + interface non-inherited method compatibility\n\
+\ intfRedundant find redundant superinterfaces\n\
+\ javadoc invalid javadoc\n\
+\ localHiding local variable hiding another variable\n\
+\ maskedCatchBlock + hidden catch block\n\
+\ nls string literal lacking non-nls tag //$NON-NLS-<n>$\n\
+\ noEffectAssign + assignment without effect\n\
+\ null potential missing or redundant null check\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\
+\ roleinstantiation + unsafe instantiation of a role\n\
+\ (OTJLD 2.4.1(c), 2.4.3)\n\
+\ roletypesyntax + old style syntax for role types (dependent types)\n\
+\ (OTJLD 1.2.2(b))\n\
+\ semicolon unnecessary semicolon, empty statement\n\
+\ serial + missing serialVersionUID\n\
+\ specialParamHiding constructor or setter parameter hiding a field\n\
+\ static-access macro for indirectStatic and staticReceiver\n\
+\ staticReceiver + non-static reference to static member\n\
+\ super overriding a method without making a super invocation\n\
+\ suppress + enable @SuppressWarnings\n\
+\ syncOverride missing synchronized in synchr. method override\n\
+\ syntheticAccess synthetic access for innerclass\n\
+\ tasks(<tags separated by |>) tasks identified by tags inside comments\n\
+\ typeHiding + type parameter hiding another type\n\
+\ unchecked + unchecked type operation\n\
+\ unnecessaryElse unnecessary else clause\n\
+\ unqualifiedField unqualified reference to field\n\
+\ unused macro for unusedAllocation, unusedArgument,\n\
+\ unusedImport, unusedLabel, unusedLocal,\n\
+\ unusedPrivate, unusedThrown, and unusedTypeArgs\n\
+\ unusedAllocation allocating an object that is not used\n\
+\ unusedArgument unread method parameter\n\
+\ unusedImport + unused import declaration\n\
+\ unusedLabel + unused label\n\
+\ unusedLocal + unread local variable\n\
+\ unusedPrivate + unused private member declaration\n\
+\ unusedThrown unused declared thrown exception\n\
+\ unusedTypeArgs + unused type arguments for method\n\
+\ uselessTypeCheck unnecessary cast/instanceof operation\n\
+\ varargsCast + varargs argument need explicit cast\n\
+\ warningToken + unsupported or unnecessary @SuppressWarnings\n
+## SH}
diff --git a/org.eclipse.jdt.core/build-jars.xml b/org.eclipse.jdt.core/build-jars.xml
new file mode 100644
index 0000000..22af7b2
--- /dev/null
+++ b/org.eclipse.jdt.core/build-jars.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="build" default="plugin_export">
+ <target name="plugin_export">
+ <pde.exportPlugins plugins="org.eclipse.jdt.core" destination="/home/local/tmp/updates" exportType="directory" useJARFormat="true" exportSource="false"/>
+ </target>
+</project>
diff --git a/org.eclipse.jdt.core/build.properties b/org.eclipse.jdt.core/build.properties
new file mode 100644
index 0000000..db0307d
--- /dev/null
+++ b/org.eclipse.jdt.core/build.properties
@@ -0,0 +1,42 @@
+###############################################################################
+# Copyright (c) 2000, 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
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+###############################################################################
+customBuildCallbacks=customBuildCallbacks.xml
+bin.includes = plugin.xml,\
+ plugin.properties,\
+ about.html,\
+ .,\
+ jdtCompilerAdapter.jar,\
+ .options,\
+ META-INF/
+javadoc.packages = org.eclipse.jdt.core.*,\
+ org.eclipse.jdt.core.formatter.*,\
+ org.eclipse.jdt.core.compiler.*,\
+ org.eclipse.jdt.core.eval.*,\
+ org.eclipse.jdt.core.jdom.*,\
+ org.eclipse.jdt.core.dom.*,\
+ org.eclipse.jdt.core.dom.rewrite.*,\
+ org.eclipse.jdt.core.search.*
+source.. = batch/,\
+ codeassist/,\
+ compiler/,\
+ eval/,\
+ formatter/,\
+ dom/,\
+ search/,\
+ model/,\
+ util/
+output.. = bin/
+output.jdtCompilerAdapter.jar = antbin/
+source.jdtCompilerAdapter.jar = antadapter/
+jars.compile.order=.,jdtCompilerAdapter.jar
+jars.extra.classpath=platform:/plugin/org.apache.ant/lib/ant.jar
+src.includes = about.html,\
+ schema/
diff --git a/org.eclipse.jdt.core/buildnotes_jdt-core.html b/org.eclipse.jdt.core/buildnotes_jdt-core.html
new file mode 100644
index 0000000..9efe5b5
--- /dev/null
+++ b/org.eclipse.jdt.core/buildnotes_jdt-core.html
@@ -0,0 +1,992 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="IBM">
+ <title>JDT/Core Release Notes 3.6</title>
+ <link rel="stylesheet" href="jdt_core_style.css" charset="iso-8859-1" type="text/css">
+</head>
+<body text="#000000" bgcolor="#FFFFFF">
+<table border=0 cellspacing=5 cellpadding=2 width="100%" >
+ <tr>
+ <td align="left" width="72%" class="title1">
+ <font size="+3"><b>jdt core - build notes 3.6 stream</b></font>
+ </td>
+ </tr>
+ <tr><td align="left" width="72%" class="title2"><font size="-2">Java development tools core</font></td></tr>
+ <tr><td> </td></tr>
+ <tr>
+ <td class="title3">
+ <font size="-1">
+ Here are the build notes for the Eclipse JDT/Core plug-in project
+ <a href="http://www.eclipse.org/jdt/core/index.php"><b>org.eclipse.jdt.core</b></a>,
+ describing <a href="https://bugs.eclipse.org/bugs" target=new>bug</a> resolution and substantial changes in the <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core"><b>HEAD</b></a> branch.
+ For more information on 3.6 planning, please refer to <a href="http://www.eclipse.org/jdt/core/r3.6/index.php#release-plan">JDT/Core release plan</a>,
+ the next <a href="http://www.eclipse.org/jdt/core/r3.6/index.php#milestone-plan">milestone plan</a>,
+ the overall <a href="http://www.eclipse.org/eclipse/development/eclipse_project_plan_3_6.html">official plan</a>,
+ or the <a href="http://www.eclipse.org/eclipse/platform-releng/buildSchedule.html">build schedule</a>.
+ This present document covers all changes since Release 3.5 (also see a summary of <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/org.eclipse.jdt.core/notes/API_changes.html">API changes</a>).
+ <br>Maintenance of previous releases of JDT/Core is performed in parallel branches:
+ <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_5_maintenance">R3.5.x</a>,
+ <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_4_maintenance">R3.4.x</a>,
+ <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_3_maintenance">R3.3.x</a>,
+ <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_2_maintenance">R3.2.x</a>,
+ <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_1_maintenance">R3.1.x</a>,
+ <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_0_maintenance">R3.0.x</a>,
+ <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R2_1_maintenance">R2.1.x</a>,
+ <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R2_0_1">R2.0.x</a>,
+ <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=ECLIPSE_1_0">R1.0.x</a>.
+ </font>
+ </td>
+ </tr>
+</table>
+<a name="v_A32a"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6M5 - January 21, 2010 - 3.6.0 M5
+<br>Project org.eclipse.jdt.core v_A32a
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A32a">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=300133">300133</a>
+[1.5][compiler] Local classes inside enum constants generate default constructor without implicit constructor call
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=300440">300440</a>
+icu dependency needs to be udpated
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=299900">299900</a>
+[null]Missing potential null warnings for variable on the right of an OR conditional expression
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=293917">293917</a>
+Invalid 'potential null access' warning reports
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=252379">252379</a>
+Organize imports deletes needed static import.
+
+<a name="v_A31"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6M5 - January 18, 2010
+<br>Project org.eclipse.jdt.core v_A31
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A31">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>New API to fix bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=295894">295894</a>. See the bug for details.
+<pre>
+/**
+ * Returns a Java search scope limited to the hierarchy of the given type and to a given project.
+ * The Java elements resulting from a search with this scope will be types in this hierarchy.
+ *
+ * Unlike the createHierarchyScope methods, this method creates strict
+ * scopes that only contain types that actually span the hierarchy of the focus
+ * type, but do not include additional enclosing or member types.
+ *
+ *
+ * By default, hierarchy scopes include all direct and indirect supertypes and subtypes of the
+ * focus type. This method, however, allows to restrict the hierarchy to true subtypes,
+ * not including supertypes. Also inclusion of the focus type itself is controled by a parameter.
+ *
+ *
+ * @param project the project to which to constrain the search, or null if
+ * search should consider all types in the workspace
+ * @param type the focus of the hierarchy scope
+ * @param onlySubtypes if true only subtypes of type are considered
+ * @param includeFocusType if true the focus type type is included in the resulting scope,
+ * otherwise it is excluded
+ * @param owner the owner of working copies that take precedence over original compilation units,
+ * or null if the primary working copy owner should be used
+ * @return a new hierarchy scope
+ * @exception JavaModelException if the hierarchy could not be computed on the given type
+ * @since 3.6
+ */
+public static IJavaSearchScope createStrictHierarchyScope(IJavaProject project, IType type, boolean onlySubtypes, boolean includeFocusType, WorkingCopyOwner owner) throws JavaModelException;
+</pre>
+</li>
+<li>New API added to report a compiler warning when object allocations are unused:
+<pre>
+org.eclipse.jdt.core.compiler.IProblem.UnusedObjectAllocation
+
+/**
+ * Compiler option ID: Reporting Allocation of an Unused Object.
+ * When enabled, the compiler will issue an error or a warning if an object is allocated but never used,
+ * neither by holding a reference nor by invoking one of the object's methods.
+ *
+ * Option id:"org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation"
+ * Possible values:{ "error", "warning", "ignore" }
+ * Default:"ignore"
+ *
+ * @since 3.6
+ * @category CompilerOptionID
+ */
+public static final String COMPILER_PB_UNUSED_OBJECT_ALLOCATION = PLUGIN_ID + ".compiler.problem.unusedObjectAllocation";
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=245007">245007</a>
+[compiler] Should not completely ignore anonymous type with missing super type
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=295894">295894</a>
+[search] Search shows focus type implementation for nested types even though the scope is restricted to subtypes.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=236385">236385</a>
+[compiler] Warn for potential programming problem if an object is created but not used
+
+<a name="v_A30"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6M5 - January 12, 2010
+<br>Project org.eclipse.jdt.core v_A30
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A30">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>New API added to expose the reconcile flags used in the reconcile context:
+<pre>
+/**
+ * Returns the reconcile flag of this context. This flag is a bitwise value of the constant defined
+ * in ICompilationUnit.
+ *
+ * @return the reconcile flag of this context
+ * @since 3.6
+ *
+ * @see ICompilationUnit#ENABLE_BINDINGS_RECOVERY
+ * @see ICompilationUnit#ENABLE_STATEMENTS_RECOVERY
+ * @see ICompilationUnit#IGNORE_METHOD_BODIES
+ */
+public int getReconcileFlags();
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=243917">243917</a>
+[compiler] should not warn about unused field when native method present
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=296343">296343</a>
+OOM error caused by java indexing referencing classloader from threadLocal
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=130000">130000</a>
+[API] ReconcileContext API: Does getAST3 return AST with bindings?
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=298238">298238</a>
+Unresolved import in superclass causes 'Cannot reduce the visibility of the inherited method' in subclass
+
+<a name="v_A29a"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6M5 - January 5, 2010
+<br>Project org.eclipse.jdt.core v_A29a
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A29a">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=293861">293861</a>
+Problem with refactoring when existing jar with invalid package names
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=264112">264112</a>
+[Formatter] Wrap when necessary too aggressive on short qualifiers
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=298250">298250</a>
+[1.6][compiler] NegativeArraySizeException in StackMapFrame.duplicate
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=296998">296998</a>
+Unused imports should not prevent execution
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=298243">298243</a>
+[formatter] Removing empty lines between import groups
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=297546">297546</a>
+[formatter] Formatter removes blank after @see if reference is wrapped
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=235781">235781</a>
+[compiler] difference to javac in definite unassignment analysis involving an exception within a constructor
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=235783">235783</a>
+[eval] CodeSnippetParser and some 'CodeSnippet*' ast node does not seem up to date
+
+<a name="v_A28"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6M5 - December 14, 2009
+<br>Project org.eclipse.jdt.core v_A28
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A28">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=196714">196714</a>
+[comment] InvalidInputException prevents the AbstractCommentMapper to retrieve tag element
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=297757">297757</a>
+Cannot get bindings for IType corresponding to parameterized anonymous type
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=255640">255640</a>
+[spec] Methods Signature.toCharArray(..) have unclear precondition
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=262898">262898</a>
+BufferChangedEvent must not have @noinstantiate
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=181682">181682</a>
+JavaConventions.validateJavaTypeName should list valid constants
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=108784">108784</a>
+SourceMapper doesn't find name range of inner class constructors
+
+<a name="v_A27"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6M4 - December 8, 2009 - 3.6.0 M4
+<br>Project org.eclipse.jdt.core v_A27
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A27">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=297225">297225</a>
+[formatter] Indentation may be still wrong in certain circumstances after formatting
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=293697">293697</a>
+JavaSearchBugTests.testBug286379c is failing randomly
+
+<a name="v_A26"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6M4 - December 7, 2009
+<br>Project org.eclipse.jdt.core v_A26
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A26">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=297045">297045</a>
+Weird tests failures in N20091204-2000 and N20091205-2000 builds
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=293300">293300</a>
+[formatter] The formatter is still unstable in certain circumstances
+
+<a name="v_A25"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6M4 - December 4, 2009
+<br>Project org.eclipse.jdt.core v_A25
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A25">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Match result can now report the access rules through a new API added on <code>TypeNameMatch</code>:
+<pre>
+/**
+ * Returns the accessibility of the type name match
+ *
+ * @see IAccessRule
+ *
+ * @return the accessibility of the type name which may be
+ * {@link IAccessRule#K_ACCESSIBLE}, {@link IAccessRule#K_DISCOURAGED}
+ * or {@link IAccessRule#K_NON_ACCESSIBLE}.
+ * The default returned value is {@link IAccessRule#K_ACCESSIBLE}.
+ *
+ * @since 3.6
+ */
+public abstract int getAccessibility();
+</pre>
+See bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=296277">296277</a> for more details.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=296277">296277</a>
+[search] SearchEngine#searchAllTypeNames(.., TypeNameMatchRequestor,..) should report access rules
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=296708">296708</a>
+[DOM/AST] clarify setters when createASTs(..) is used
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=296629">296629</a>
+[quick fix] Cast quick fix not offered for method-local classes
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=295948">295948</a>
+ElementImpl.hashCode throws an NPE
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=296660">296660</a>
+[compiler] Incorrect unused method warning from compiler
+
+<a name="v_A24"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6M4 - December 1, 2009
+<br>Project org.eclipse.jdt.core v_A24
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A24">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>New API added to ignore method bodies inside AST tree. The new APIs are tagged as 3.5.2 as this code
+will be backported to 3.5.2:
+<pre>
+org.eclipse.jdt.core.dom.ASTParser:
+ /**
+ * Requests an abstract syntax tree without method bodies.
+ *
+ * When ignore method bodies is enabled, all method bodies are discarded.
+ * This has no impact on the binding resolution.
+ *
+ * If a method contains local types, its method body will be retained.
+ * This settings is not used if the kind used in setKind(int) is either
+ * K_EXPRESSION or K_STATEMENTS.
+ * @since 3.5.2
+ */
+ public void setIgnoreMethodBodies(boolean enabled);
+
+org.eclipse.jdt.core.ICompilationUnit:
+ /**
+ * Constant indicating that a reconcile operation could ignore to parse the method bodies.
+ * @see ASTParser#setIgnoreMethodBodies(boolean)
+ * @since 3.5.2
+ */
+ public static final int IGNORE_METHOD_BODIES = 0x08;
+
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=288174">288174</a>
+[search] NullPointerException when searching for type references
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=277643">277643</a>
+Generics compile error
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=288211">288211</a>
+APT uses a lot of memory
+
+<a name="v_A23"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6M4 - November 24, 2009
+<br>Project org.eclipse.jdt.core v_A23
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A23">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=295698">295698</a>
+[1.5][compiler] ClassCastException in unchecked warning report
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=295260">295260</a>
+Wrong warnings on Java.Compiler.Errors/Warnings "Redundant null check"
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=190737">190737</a>
+[compiler][null] missing 'cannot be null' warning within for loop
+
+<a name="v_A22"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6M4 - November 16, 2009
+<br>Project org.eclipse.jdt.core v_A22
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A22">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=153429">153429</a>
+JUnit4 in Eclipse Testing Framework
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=295238">295238</a>
+[formatter] The comment formatter add an unexpected new line in block comment
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=295175">295175</a>
+[formatter] Missing space before a string at the beginning of a line in a javadoc comment
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=294529">294529</a>
+The Scanner sometimes ignores the given offset if larger than the EOF.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=294662">294662</a>
+ClassCastException while invoking quick assist
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=294404">294404</a>
+-target jsr14 flags error on foreach over Collection that does not implement Iterable
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=293955">293955</a>
+valid javadoc url set on user library, but still says no javadoc
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=293443">293443</a>
+AbortCompilation when invoking content assist
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=293711">293711</a>
+Clarify ICompilationUnit#getOwner() javadoc
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=293615">293615</a>
+error message since v3.6.0M2: name clash by overriding generic methods
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=294618">294618</a>
+[formatter] The formatter fails to format a compilation unit with deep nesting of html tags
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=248312">248312</a>
+[model] IMemberValuePair#getValue() should also work for negative numerals
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=294731">294731</a>
+Specify value type of JAVADOC_LOCATION_ATTRIBUTE_NAME
+
+<a name="v_A21"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6M4 - November 10, 2009
+<br>Project org.eclipse.jdt.core v_A21
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A21">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=294631">294631</a>
+[formatter] The formatter takes two passes to format a common sequence of html tags
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=294500">294500</a>
+[formatter] MalformedTreeException when formatting an invalid sequence of <code> tags in a javadoc comment
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=294488">294488</a>
+Javadoc of ISourceReference#getSourceRange() should link to SourceRange#isAvailable(..)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=199265">199265</a>
+[formatter] 3.3 Code Formatter mis-places commented-out import statements
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=241549">241549</a>
+[spec] IType#getFields/Initializers/Methods() should define order from class file
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=275805">275805</a>
+creating a non-primary working copy causes typeHierarchyChanged event
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=292510">292510</a>
+FUP of 292364: Error messages don't identify partial types precisely.
+
+<a name="v_A20"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6M4 - November 3, 2009
+<br>Project org.eclipse.jdt.core v_A20
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A20">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=293384">293384</a>
+Eclipse erroneously reports method "is ambiguous for type"
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=285002">285002</a>
+[compiler] visibility error for package private method
+
+<a name="v_A19"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6M3 - October 29, 2009 - 3.6M3
+<br>Project org.eclipse.jdt.core v_A19
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A19">cvs</a>).
+<h2>What's new in this drop</h2>
+This version was created to tentatively fix bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=293697">293697</a>
+but it occurs again in subsequent build. So, it has been reopened and moved to next version...
+
+<h3>Problem Reports Fixed</h3>
+
+<a name="v_A18"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6M3 - October 28, 2009
+<br>Project org.eclipse.jdt.core v_A18
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A18">cvs</a>).
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=293496">293496</a>
+Adding the serialVersionUID field doesn't work when tab size is 0
+
+<a name="v_A17"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6M3 - October 26, 2009
+<br>Project org.eclipse.jdt.core v_A17
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A17">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Reverted change for bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=263564">263564</a>.</li>
+</ul>
+<h3>Problem Reports Fixed</h3>
+
+<a name="v_A16"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6M3 - October 25, 2009
+<br>Project org.eclipse.jdt.core v_A16
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A16">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>New API added in <code>org.eclipse.jdt.core.JavaCore</code> in order to fix bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=263564">263564</a>:
+<pre>
+ /**
+ * Returns an immutable map of all known configurable options with their original default values
+ * as defined by JDT/Core.
+ *
+ * The values of these options might be different from the values returned by getDefaultOptions()
+ * as getDefaultOptions() returned the default options defined by an installation/product/configuration
+ * (i.e. modified by the usage of a plugin_customization.ini file for example).
+ *
+ * These options allow to configure the behaviour of the underlying components.
+ * If the map is being modified, an UnsupportedOperationException> exception is thrown.
+ * Helper constants have been defined on JavaCore for each of the option IDs
+ * (categorized in Code assist option ID, Compiler option ID and Core option ID)
+ * and some of their acceptable values (categorized in Option value). Some
+ * options accept open value sets beyond the documented constant values.
+ * Note: each release may add new options.
+ *
+ * @return an immutable map of all known configurable options with their original default values
+ * as defined by JDT/Core
+ * @since 3.6
+ */
+ public static Map getOriginalDefaultOptions();
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=293240">293240</a>
+[formatter] 'insert_space_before_opening_brace_in_array_initializer' preference may be reset in certain circumstances
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=263564">263564</a>
+API to know when default compiler preference settings have been altered
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=289385">289385</a>
+Investigate comment in performance tests
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=286379">286379</a>
+[search] Problem while searching class
+
+<a name="v_A15"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6M3 - October 20, 2009
+<br>Project org.eclipse.jdt.core v_A15
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A15">cvs</a>).
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=292350">292350</a>
+[1.5][compiler] Compiler error: ambiguous method since 3.5.1 using generics and interface inheritance
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=292364">292364</a>
+[internal] Type name in CastExpression not treated as Type name.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=292428">292428</a>
+Internal compiler error: NullPointerException at org.eclipse.jdt.internal.compiler.ast.CastExpression.checkUnsafeCast(CastExpression.java:333)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=291985">291985</a>
+[compiler][jsr14] Translating Enum with jsr14 target: ECJ causes a runtime error while Sun compiler works fine
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=292240">292240</a>
+Compiler error on implementation of raw sub interface
+
+<a name="v_A14"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6M3 - October 13, 2009
+<br>Project org.eclipse.jdt.core v_A14
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A14">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=291391">291391</a>
+update the Bundle-Version of the JDT Core Batch Compiler (ecj) from 3.3.0 to 3.6.*
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=284280">284280</a>
+[1.5][compiler] Error on use generic interface in abstract super class
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=286228">286228</a>
+[1.5][compiler] Generics inconsistencies possible regression
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=286601">286601</a>
+[formatter] Code formatter formats anonymous inner classes wrongly when 'Never join lines' is on
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=215139">215139</a>
+[search] More options for HierarchyScope
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=291472">291472</a>
+[1.5][compiler] Access to a generic method is compiled incorrectly
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=283539">283539</a>
+NamingConventions.suggestVariableNames doesn't work if name contains '_'
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=280784">280784</a>
+[batch] Allow access restrictions to be reported as errors
+
+<a name="v_A13"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6M3 - October 6, 2009
+<br>Project org.eclipse.jdt.core v_A13
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A13">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Reverted fix for <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=106478">106478</a>.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=291322">291322</a>
+Test errors when running JDT Core tests on Windows 7
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=282770">282770</a>
+[compiler] Dead code detection should have specific @SuppressWarnings
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=290028">290028</a>
+Use IResource#setDerived(boolean, IProgressMonitor) instead of IResource#setDerived(boolean)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=287607">287607</a>
+[1.5][compiler] cast of inner of generic enclosing type are not reported as unsafe
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=288749">288749</a>
+Redundant superinterface not flagged inside one declaration
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=290905">290905</a>
+[formatter] Certain formatter pref constellation cause endless loop ==> OOME
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=285124">285124</a>
+serialVersionUID still causes error/warning
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=290877">290877</a>
+[DOM] If using a tag named '@enum' the ASTParser ignores this
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=281575">281575</a>
+Eclipse hangs in SourceMapper while doing java proposals
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=290470">290470</a>
+[JSR199][compiler] JDT compiler not jsr199 compatible.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=290730">290730</a>
+Rewriting SwitchStatement throws NPE
+
+<a name="v_A12"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6M3 - September 29, 2009
+<br>Project org.eclipse.jdt.core v_A12
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A12">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=287676">287676</a>
+[1.5][compiler] Useless cast warning not emited
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=290563">290563</a>
+add specification for fine grain search flags
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=290376">290376</a>
+Errant "Comparing identical expressions" warning with assignment
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=287592">287592</a>
+[1.5][compiler] Wrong ambiguous compilation error
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=290049">290049</a>
+Reconciling a compilation unit does not return an AST with bindings when it should (probably)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=290034">290034</a>
+Effects of @SuppressWarnings("unchecked") are broader in Eclipse than in javac
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=267561">267561</a>
+[evaluation] LocalEvaluationEngine does not accept primitive types
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=163194">163194</a>
+[1.6] compiler should warn about missing @Override annotation for interface method
+
+<a name="v_A11"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6M3 - September 22, 2009
+<br>Project org.eclipse.jdt.core v_A11
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A11">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=289892">289892</a>
+[compiler] NPE during binaryTypeBinding field initialization
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=287833">287833</a>
+[formatter] Formatter removes the first character after the * in the <pre> tag
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=238943">238943</a>
+SortElementsOperation doesn't use project specific settings
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=288621">288621</a>
+[1.5][compiler] Creating type hierarchy failed when pressing F4
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=289538">289538</a>
+[1.5][compiler] compiler fails to generate correct code for private constructor in inner class
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=289639">289639</a>
+Problems opening perspective JavaPerspective, NPE on JavaModelManager.containersReset()
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=289516">289516</a>
+Annotations (visible and invisible) should be preserved with target jsr14
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=289576">289576</a>
+[1.5][compiler] Compiler changes 'private' modifier on methods with annotated parameter
+
+<a name="v_A10"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6M2 - September 14, 2009 - 3.6M2
+<br>Project org.eclipse.jdt.core v_A10
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A10">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=288148">288148</a>
+[perfs] Comments applied for performance tests may be obsolete
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=289247">289247</a>
+[1.5][compiler]Detecting duplicate methods should not consider return type
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=288920">288920</a>
+[compiler] NPE renaming run() method
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=288698">288698</a>
+Cannot create type hierarchy for abstract types when they have inline descendants and *.class* in project name
+
+<a name="v_A09"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6M2 - September 1, 2009
+<br>Project org.eclipse.jdt.core v_A09
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A09">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=287009">287009</a>
+Inner Annotation Checks are Missing
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=287701">287701</a>
+[dom] Length of Assignment should not include whitespace
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=285230">285230</a>
+[performance] Duplicate buffers created for internal classes
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=286391">286391</a>
+[compiler] jsr14 target behavior changed between ECJ 3.4.2 and ECJ 3.5
+
+<a name="v_A08"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6M2 - August 25, 2009
+<br>Project org.eclipse.jdt.core v_A08
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A08">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=287462">287462</a>
+[formatter] new failures in last 2 nightly builds
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=285565">285565</a>
+[inline] Inlining constant or local variables causes exceptions with tab width 0
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=285799">285799</a>
+HashtableOfObject rehashes and grows buffer on removeKey()
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=286912">286912</a>
+[formatter] Never join lines preferences makes the formatter unstable in certain circumstances
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=286668">286668</a>
+[formatter] 'Never Join Lines' joins lines that are split on method invocation
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=248661">248661</a>
+Axis2: Missing required libraries in Axis 2 WS Client Projects
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=286918">286918</a>
+[javadoc] Compiler should warn when @see and @link tag references in package-info.java don't have fully qualified names
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=285466">285466</a>
+[3.5 regression] fails to build IcedTea, works with 3.4.x
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=286956">286956</a>
+NPE when asking to externalize constant
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=281609">281609</a>
+[javadoc] "Javadoc: Invalid reference" warning for @link to Java package
+
+<a name="v_A07"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6M2 - August 18, 2009
+<br>Project org.eclipse.jdt.core v_A07
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A07">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=286840">286840</a>
+ClasspathJar getPath() should return a unique path
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=254738">254738</a>
+NPE in HierarchyResolver.setFocusType
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=276294">276294</a>
+Error does not go away after it is resolved
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=284785">284785</a>
+[1.5][compiler] Eclipse compiler shows error on javac-valid construct: varargs plus overload
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=286405">286405</a>
+Default value character of annotations in ClassFileEditor are badly printed
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=286407">286407</a>
+[Model] IMemberValuePair don't return the right value for java.lang.annotation.RetentionPolicy annotations
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=285701">285701</a>
+[1.5][compiler] Internal Compiler Error - ArrayIndexOutOfBoundsException
+
+<a name="v_A06"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6M1 - August 3, 2009 - 3.6M1
+<br>Project org.eclipse.jdt.core v_A06
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A06">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=284948">284948</a>
+[1.6][compiler] Java annotations are broken in editor when used on interface methods
+
+<a name="v_A05"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6M1 - July 30, 2009
+<br>Project org.eclipse.jdt.core v_A05
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A05">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=276526">276526</a>
+[content assist] Error - Type Duplicate interface Iterable for the type TestClass
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=191176">191176</a>
+JavaProject#getOption optimizations
+
+<a name="v_A04"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6M1 - July 28, 2009
+<br>Project org.eclipse.jdt.core v_A04
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A04">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=261909">261909</a>
+ClassFileReader.getModifiers() answers funny bits
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=283225">283225</a>
+[1.6][compiler] classfile versus source conformance check too strict
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=284679">284679</a>
+[formatter] empty single semi statement prevent enum elements format
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=284482">284482</a>
+[compiler] Collision cases not detected
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=284431">284431</a>
+Different inherited thrown exception clauses are not properly handled
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=133911">133911</a>
+type.move() returns unclear exception "invalid destination"
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=270436">270436</a>
+[assist] Interface type proposed where only class is legal
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=210385">210385</a>
+[compiler] ProblemReporter#getProblemCategory misbehaves when passed ProblemSeverities.Ignore as severity parameter
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=282891">282891</a>
+[compiler] "Comparing identical expressions" warning sometimes invalid
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=282869">282869</a>
+[compiler] Unnecessary cast warning for cast from char to int
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=270437">270437</a>
+[assist] Completion proposal leads to cycle detected error
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=217443">217443</a>
+Documentation for JavaCore#CORE_ENCODING does not match the observed behavior
+
+<a name="v_A03"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6M1 - July 21, 2009
+<br>Project org.eclipse.jdt.core v_A03
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A03">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=283467">283467</a>
+[formatter] wrong indentation with 'Never join lines' selected
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=281776">281776</a>
+Should not warn for comparison of identical expression with float type
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=282768">282768</a>
+[compiler] Dead code detection should ignore trivial case for ternary if operator
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=283133">283133</a>
+[formatter] IAE when pasting a snippet
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=283299">283299</a>
+Complete SourceRange API
+
+<a name="v_A02"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.6M1 - July 13, 2009
+<br>Project org.eclipse.jdt.core v_A02
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A02">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Added new API type org.eclipse.jdt.core.SourceRange</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=271296">271296</a>
+[assist] void typed proposal may not be appropriate in many contexts
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=281871">281871</a>
+[content assist] The extension took too long to return from the 'computeCompletionProposals()' operation
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=281598">281598</a>
+[assist] Problems during content assist - if project has empty zip file in classpath
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=235294">235294</a>
+[formatter] javadoc for DefaultCodeFormatterConstants#FORMATTER_ALIGNMENT_FOR_ASSIGNMENT cites a non-API constant
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=280497">280497</a>
+Incorrect null result for IJavaProject.getClasspathEntryFor(IPath)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=204777">204777</a>
+Clarify documentation for ITypeHierarchy created on interface types
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=88265">88265</a>
+Make SourceRange API
+
+<a name="v_A01"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6M1 - July 7, 2009
+<br>Project org.eclipse.jdt.core v_A01
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A01">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=260968">260968</a>
+Deadlock in UserLibraryManager
+
+<a name="v_A00"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6M1 - June 30, 2009
+<br>Project org.eclipse.jdt.core v_A00
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A00">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>New API added to handle the new <code>invokedynamic</code> bytecode:
+<pre>
+org.eclipse.jdt.core.util.ByteCodeVisitorAdapter:
+ public void _invokedynamic(
+ int pc,
+ int index,
+ IConstantPoolEntry nameEntry,
+ IConstantPoolEntry descriptorEntry) {
+ // default behavior is to do nothing
+ }
+</pre>
+<pre>org.eclipse.jdt.core.util.IBytecodeVisitor#_invokedynamic(int, int, IConstantPoolEntry, IConstantPoolEntry)</pre>
+<pre>org.eclipse.jdt.core.util.IOpcodeMnemonics#INVOKEDYNAMIC</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=277450">277450</a>
+[1.5][compiler] Problems with += and Autoboxing/Unboxing
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=206498">206498</a>
+[1.7][compiler] Remove fix for bug 206483 once 1.7 VMS can handle .class files with version 51.0
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=191176">191176</a>
+JavaProject#getOption optimizations
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=201762">201762</a>
+Content Assist has no proposals with certain CU structure
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=281681">281681</a>
+Stale code in CompilerOptions
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=231796">231796</a>
+[formatter] @throws tag description is not indented using @param preference when there's a syntax error
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=255142">255142</a>
+[select] Codeselect should not omit cast
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=235295">235295</a>
+[formatter] javadoc of CodeFormatter#F_INCLUDE_COMMENTS needs improvement
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=280134">280134</a>
+[1.5][compiler] Requesting Java AST from selection has encountered a problem
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=281317">281317</a>
+[search] An internal error occurred during: "Java Search".
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=276373">276373</a>
+Incorrect resource comparison with IJavaProject.isOnClasspath(IResource)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=275518">275518</a>
+[assist] Content assist does not provide proposals if invoked right after a method's opening brace
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=280888">280888</a>
+change a java file in one plug-in will compile all related plugin projects
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=274466">274466</a>
+[assist] Assert expressions should be proposed with high relevance
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=277382">277382</a>
+NPE and other failures in Parser
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=275330">275330</a>
+NPE from org.eclipse.jdt.internal.core.ClasspathChange.requestIndexing
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=273385">273385</a>
+[model] NPE while closing project
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=280079">280079</a>
+NPE while parsing K_CLASS_BODY_DECLARATIONS
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=280063">280063</a>
+org.eclipse.jdt.internal.compiler.parser.Parser.parseClassBodyDeclarations(char[], int, int, CompilationUnitDeclaration) should return consistent results
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=267046">267046</a>
+SourceMapper infinite loop on primitive type in generic
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=240934">240934</a>
+Add support for the invokedynamic bytecode into the disassembler
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=267551">267551</a>
+[formatter] Wrong spacing in default array parameter for annotation type
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=277965">277965</a>
+[compiler] NPE in canBeSeenBy due to illegal protected toplevel class
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=273990">273990</a>
+[compiler] FUP of 269388: Eclipse accepts code rejected by javac
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=279183">279183</a>
+[1.6][compiler] Inconsistent stackmap frames generated by JDT cause VerifyError
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=209778">209778</a>
+[search] TypeReferenceMatch#getOtherElements() fails for match in annotation
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=221065">221065</a>
+[search] Search still finds overridden method
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=279836">279836</a>
+[1.5][compiler] Eclipse compiler shows error on javac-valid construct: raw types on overridden methods
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=280616">280616</a>
+[formatter] Valid 1.5 code is not formatted inside <pre> tag
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=280255">280255</a>
+[formatter] Format edited lines adds two new lines on each save
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=280061">280061</a>
+[formatter] AIOOBE while formatting javadoc comment
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=276938">276938</a>
+Remove unreachable removes reachable logic in case statement.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=274898">274898</a>
+[recovery] IllegalArgumentException in ASTNode#setSourceRange()
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=277204">277204</a>
+IAE in SharedASTProvider for generic local class.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=276741">276741</a>
+comparing identical value detection does not work for this
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=276740">276740</a>
+comparing identical value detection does not work for primitive types
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=278745">278745</a>
+Methods overloaded with unavailable types worked in 3.4 but give "indirectly referenced.." error in 3.5
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=278305">278305</a>
+[1.5][compiler] JDT accepts supertype parameterized with wildcard
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=196308">196308</a>
+[formatter] Don't escape entity when formatting in <pre> tags within javadoc comments
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=279359">279359</a>
+[formatter] Formatter with 'never join lines' produces extra level of indent
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=273619">273619</a>
+[formatter] Formatting repeats *} in javadoc
+
+<hr>
+<p>For earlier build notes, also see <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/org.eclipse.jdt.core/notes/R35_buildnotes_jdt-core.html">build notes up to Release 3.5</a>.</p>
+<br>
+ <p>
+ <a href="http://validator.w3.org/check?uri=referer"><img
+ src="http://www.w3.org/Icons/valid-html401"
+ alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>
+ </p>
+</body>
+</html>
+
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionElementNotifier.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionElementNotifier.java
new file mode 100644
index 0000000..99427f5
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionElementNotifier.java
@@ -0,0 +1,216 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 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
+ * 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.codeassist;
+
+import java.util.Map;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionOnAnnotationOfType;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionOnArgumentName;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionOnFieldName;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionOnFieldType;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionOnImportReference;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionOnKeyword;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionOnKeyword2;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionOnMethodName;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionOnMethodReturnType;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionOnMethodTypeParameter;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionOnPackageReference;
+import org.eclipse.jdt.internal.compiler.SourceElementNotifier;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Argument;
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.ImportReference;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfObjectToInt;
+
+public class CompletionElementNotifier extends SourceElementNotifier {
+
+ private ASTNode assistNode;
+
+ public CompletionElementNotifier(
+ CompletionUnitStructureRequestor requestor,
+ boolean reportLocalDeclarations,
+ ASTNode assistNode) {
+ super(requestor, reportLocalDeclarations);
+ this.assistNode = assistNode;
+ }
+
+ protected char[][][] getArguments(Argument[] arguments) {
+ int argumentLength = arguments.length;
+ char[][] argumentTypes = new char[argumentLength][];
+ char[][] argumentNames = new char[argumentLength][];
+ int argumentCount = 0;
+ next : for (int i = 0; i < argumentLength; i++) {
+ Argument argument = arguments[i];
+
+ if (argument instanceof CompletionOnArgumentName && argument.name.length == 0) continue next;
+
+ argumentTypes[argumentCount] = CharOperation.concatWith(argument.type.getParameterizedTypeName(), '.');
+ argumentNames[argumentCount++] = argument.name;
+ }
+
+ if (argumentCount < argumentLength) {
+ System.arraycopy(argumentTypes, 0, argumentTypes = new char[argumentCount][], 0, argumentCount);
+ System.arraycopy(argumentNames, 0, argumentNames = new char[argumentCount][], 0, argumentCount);
+ }
+
+ return new char[][][] {argumentTypes, argumentNames};
+ }
+
+ protected char[][] getInterfaceNames(TypeDeclaration typeDeclaration) {
+ char[][] interfaceNames = null;
+ int superInterfacesLength = 0;
+ TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
+ if (superInterfaces != null) {
+ superInterfacesLength = superInterfaces.length;
+ interfaceNames = new char[superInterfacesLength][];
+ } else {
+ if ((typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) {
+ // see PR 3442
+ QualifiedAllocationExpression alloc = typeDeclaration.allocation;
+ if (alloc != null && alloc.type != null) {
+ superInterfaces = new TypeReference[] { alloc.type};
+ superInterfacesLength = 1;
+ interfaceNames = new char[1][];
+ }
+ }
+ }
+ if (superInterfaces != null) {
+ int superInterfaceCount = 0;
+ next: for (int i = 0; i < superInterfacesLength; i++) {
+ TypeReference superInterface = superInterfaces[i];
+
+ if (superInterface instanceof CompletionOnKeyword) continue next;
+ if (CompletionUnitStructureRequestor.hasEmptyName(superInterface, this.assistNode)) continue next;
+
+ interfaceNames[superInterfaceCount++] = CharOperation.concatWith(superInterface.getParameterizedTypeName(), '.');
+ }
+
+ if (superInterfaceCount == 0) return null;
+ if (superInterfaceCount < superInterfacesLength) {
+ System.arraycopy(interfaceNames, 0, interfaceNames = new char[superInterfaceCount][], 0, superInterfaceCount);
+ }
+ }
+ return interfaceNames;
+ }
+
+ protected char[] getSuperclassName(TypeDeclaration typeDeclaration) {
+ TypeReference superclass = typeDeclaration.superclass;
+
+ if (superclass instanceof CompletionOnKeyword) return null;
+ if (CompletionUnitStructureRequestor.hasEmptyName(superclass, this.assistNode)) return null;
+
+ return superclass != null ? CharOperation.concatWith(superclass.getParameterizedTypeName(), '.') : null;
+ }
+
+ protected char[][] getThrownExceptions(AbstractMethodDeclaration methodDeclaration) {
+ char[][] thrownExceptionTypes = null;
+ TypeReference[] thrownExceptions = methodDeclaration.thrownExceptions;
+ if (thrownExceptions != null) {
+ int thrownExceptionLength = thrownExceptions.length;
+ int thrownExceptionCount = 0;
+ thrownExceptionTypes = new char[thrownExceptionLength][];
+ next : for (int i = 0; i < thrownExceptionLength; i++) {
+ TypeReference thrownException = thrownExceptions[i];
+
+ if (thrownException instanceof CompletionOnKeyword) continue next;
+ if (CompletionUnitStructureRequestor.hasEmptyName(thrownException, this.assistNode)) continue next;
+
+ thrownExceptionTypes[thrownExceptionCount++] =
+ CharOperation.concatWith(thrownException.getParameterizedTypeName(), '.');
+ }
+
+ if (thrownExceptionCount == 0) return null;
+ if (thrownExceptionCount < thrownExceptionLength) {
+ System.arraycopy(thrownExceptionTypes, 0, thrownExceptionTypes = new char[thrownExceptionCount][], 0, thrownExceptionCount);
+ }
+ }
+ return thrownExceptionTypes;
+ }
+
+ protected char[][] getTypeParameterBounds(TypeParameter typeParameter) {
+ TypeReference firstBound = typeParameter.type;
+ TypeReference[] otherBounds = typeParameter.bounds;
+ char[][] typeParameterBounds = null;
+ if (firstBound != null) {
+ if (otherBounds != null) {
+ int otherBoundsLength = otherBounds.length;
+ char[][] boundNames = new char[otherBoundsLength+1][];
+ int boundCount = 0;
+ if (!CompletionUnitStructureRequestor.hasEmptyName(firstBound, this.assistNode)) {
+ boundNames[boundCount++] = CharOperation.concatWith(firstBound.getParameterizedTypeName(), '.');
+ }
+ for (int j = 0; j < otherBoundsLength; j++) {
+ TypeReference otherBound = otherBounds[j];
+ if (!CompletionUnitStructureRequestor.hasEmptyName(otherBound, this.assistNode)) {
+ boundNames[boundCount++] =
+ CharOperation.concatWith(otherBound.getParameterizedTypeName(), '.');
+ }
+ }
+
+ if (boundCount == 0) {
+ boundNames = CharOperation.NO_CHAR_CHAR;
+ } else if (boundCount < otherBoundsLength + 1){
+ System.arraycopy(boundNames, 0, boundNames = new char[boundCount][], 0, boundCount);
+ }
+ typeParameterBounds = boundNames;
+ } else {
+ if (!CompletionUnitStructureRequestor.hasEmptyName(firstBound, this.assistNode)) {
+ typeParameterBounds = new char[][] { CharOperation.concatWith(firstBound.getParameterizedTypeName(), '.')};
+ } else {
+ typeParameterBounds = CharOperation.NO_CHAR_CHAR;
+ }
+ }
+ } else {
+ typeParameterBounds = CharOperation.NO_CHAR_CHAR;
+ }
+
+ return typeParameterBounds;
+ }
+
+ protected void notifySourceElementRequestor(AbstractMethodDeclaration methodDeclaration, TypeDeclaration declaringType, ImportReference currentPackage) {
+ if (methodDeclaration instanceof CompletionOnMethodReturnType) return;
+ if (methodDeclaration instanceof CompletionOnMethodTypeParameter) return;
+ if (methodDeclaration instanceof CompletionOnMethodName) return;
+ super.notifySourceElementRequestor(methodDeclaration, declaringType, currentPackage);
+ }
+
+ public void notifySourceElementRequestor(CompilationUnitDeclaration parsedUnit, int sourceStart, int sourceEnd, boolean reportReference, HashtableOfObjectToInt sourceEndsMap, Map nodesToCategoriesMap) {
+ super.notifySourceElementRequestor(parsedUnit, sourceStart, sourceEnd, reportReference, sourceEndsMap, nodesToCategoriesMap);
+ }
+
+ protected void notifySourceElementRequestor(FieldDeclaration fieldDeclaration, TypeDeclaration declaringType) {
+ if (fieldDeclaration instanceof CompletionOnFieldType) return;
+ if (fieldDeclaration instanceof CompletionOnFieldName) return;
+ super.notifySourceElementRequestor(fieldDeclaration, declaringType);
+ }
+
+ protected void notifySourceElementRequestor(ImportReference importReference, boolean isPackage) {
+ if (importReference instanceof CompletionOnKeyword2) return;
+ if (importReference instanceof CompletionOnImportReference ||
+ importReference instanceof CompletionOnPackageReference) {
+ if (importReference.tokens[importReference.tokens.length - 1].length == 0) return;
+ }
+
+ super.notifySourceElementRequestor(importReference, isPackage);
+ }
+
+ protected void notifySourceElementRequestor(TypeDeclaration typeDeclaration, boolean notifyTypePresence, TypeDeclaration declaringType, ImportReference currentPackage) {
+ if (typeDeclaration instanceof CompletionOnAnnotationOfType) return;
+ super.notifySourceElementRequestor(typeDeclaration, notifyTypePresence, declaringType, currentPackage);
+ }
+}
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
new file mode 100644
index 0000000..70c88bd
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
@@ -0,0 +1,13719 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 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
+ * $Id: CompletionEngine.java 23405 2010-02-03 17:02:18Z stephan $
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Fraunhofer FIRST - extended API and implementation
+ * Technical University Berlin - extended API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist;
+
+import java.util.ArrayList;
+import java.util.Locale;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jdt.core.CompletionContext;
+import org.eclipse.jdt.core.CompletionFlags;
+import org.eclipse.jdt.core.CompletionProposal;
+import org.eclipse.jdt.core.CompletionRequestor;
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IAccessRule;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeRoot;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.WorkingCopyOwner;
+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.core.search.IJavaSearchConstants;
+
+import org.eclipse.jdt.internal.codeassist.complete.*;
+import org.eclipse.jdt.internal.codeassist.impl.AssistParser;
+import org.eclipse.jdt.internal.codeassist.impl.Engine;
+import org.eclipse.jdt.internal.codeassist.impl.Keywords;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
+import org.eclipse.jdt.internal.compiler.ExtraFlags;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.env.*;
+import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+import org.eclipse.jdt.internal.compiler.parser.SourceTypeConverter;
+import org.eclipse.jdt.internal.compiler.parser.JavadocTagConstants;
+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
+import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
+import org.eclipse.jdt.internal.compiler.util.ObjectVector;
+import org.eclipse.jdt.internal.core.BasicCompilationUnit;
+import org.eclipse.jdt.internal.core.INamingRequestor;
+import org.eclipse.jdt.internal.core.InternalNamingConventions;
+import org.eclipse.jdt.internal.core.JavaModelManager;
+import org.eclipse.jdt.internal.core.SourceMethod;
+import org.eclipse.jdt.internal.core.SourceMethodElementInfo;
+import org.eclipse.jdt.internal.core.SourceType;
+import org.eclipse.jdt.internal.core.BinaryTypeConverter;
+import org.eclipse.jdt.internal.core.SearchableEnvironment;
+import org.eclipse.jdt.internal.core.SourceTypeElementInfo;
+import org.eclipse.jdt.internal.core.search.matching.JavaSearchNameEnvironment;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.objectteams.otdt.core.compiler.IOTConstants;
+import org.eclipse.objectteams.otdt.internal.codeassist.CompletionOnFieldAccessSpec;
+import org.eclipse.objectteams.otdt.internal.codeassist.CompletionOnMethodSpec;
+import org.eclipse.objectteams.otdt.internal.core.compiler.ast.AbstractMethodMappingDeclaration;
+import org.eclipse.objectteams.otdt.internal.core.compiler.ast.CallinMappingDeclaration;
+import org.eclipse.objectteams.otdt.internal.core.compiler.ast.CalloutMappingDeclaration;
+import org.eclipse.objectteams.otdt.internal.core.compiler.ast.MethodSpec;
+import org.eclipse.objectteams.otdt.internal.core.compiler.control.Dependencies;
+import org.eclipse.objectteams.otdt.internal.core.compiler.control.ITranslationStates;
+import org.eclipse.objectteams.otdt.internal.core.compiler.control.StateHelper;
+import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.CallinCalloutScope;
+import org.eclipse.objectteams.otdt.internal.core.compiler.model.MethodModel;
+import org.eclipse.objectteams.otdt.internal.core.compiler.model.RoleModel;
+import org.eclipse.objectteams.otdt.internal.core.compiler.util.TSuperHelper;
+import org.eclipse.objectteams.otdt.internal.core.compiler.util.TypeAnalyzer;
+
+/**
+ * This class is the entry point for source completions.
+ * It contains two public APIs used to call CodeAssist on a given source with
+ * a given environment, assisting position and storage (and possibly options).
+ */
+public final class CompletionEngine
+ extends Engine
+ implements ISearchRequestor, TypeConstants , TerminalTokens , RelevanceConstants, SuffixConstants {
+
+ private static class AcceptedConstructor {
+ public int modifiers;
+ public char[] simpleTypeName;
+ public int parameterCount;
+ public char[] signature;
+ public char[][] parameterTypes;
+ public char[][] parameterNames;
+ public int typeModifiers;
+ public char[] packageName;
+ public int extraFlags;
+ public int accessibility;
+ public boolean proposeType = false;
+ public boolean proposeConstructor = false;
+ public char[] fullyQualifiedName = null;
+
+ public boolean mustBeQualified = false;
+
+ public AcceptedConstructor(
+ int modifiers,
+ char[] simpleTypeName,
+ int parameterCount,
+ char[] signature,
+ char[][] parameterTypes,
+ char[][] parameterNames,
+ int typeModifiers,
+ char[] packageName,
+ int extraFlags,
+ int accessibility) {
+ this.modifiers = modifiers;
+ this.simpleTypeName = simpleTypeName;
+ this.parameterCount = parameterCount;
+ this.signature = signature;
+ this.parameterTypes = parameterTypes;
+ this.parameterNames = parameterNames;
+ this.typeModifiers = typeModifiers;
+ this.packageName = packageName;
+ this.extraFlags = extraFlags;
+ this.accessibility = accessibility;
+ }
+
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append('{');
+ buffer.append(this.packageName);
+ buffer.append(',');
+ buffer.append(this.simpleTypeName);
+ buffer.append('}');
+ return buffer.toString();
+ }
+ }
+
+ private static class AcceptedType {
+ public char[] packageName;
+ public char[] simpleTypeName;
+ public char[][] enclosingTypeNames;
+ public int modifiers;
+ public int accessibility;
+ public boolean mustBeQualified = false;
+
+ public char[] fullyQualifiedName = null;
+ public char[] qualifiedTypeName = null;
+ public AcceptedType(
+ char[] packageName,
+ char[] simpleTypeName,
+ char[][] enclosingTypeNames,
+ int modifiers,
+ int accessibility) {
+ this.packageName = packageName;
+ this.simpleTypeName = simpleTypeName;
+ this.enclosingTypeNames = enclosingTypeNames;
+ this.modifiers = modifiers;
+ this.accessibility = accessibility;
+ }
+
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append('{');
+ buffer.append(this.packageName);
+ buffer.append(',');
+ buffer.append(this.simpleTypeName);
+ buffer.append(',');
+ buffer.append(CharOperation.concatWith(this.enclosingTypeNames, '.'));
+ buffer.append('}');
+ return buffer.toString();
+ }
+ }
+
+ public class CompletionProblemFactory extends DefaultProblemFactory {
+ private int lastErrorStart;
+
+ private boolean checkProblems = false;
+ public boolean hasForbiddenProblems = false;
+ public boolean hasAllowedProblems = false;
+
+ public CompletionProblemFactory(Locale loc) {
+ super(loc);
+ }
+
+ private CategorizedProblem checkProblem(CategorizedProblem pb,
+ char[] originatingFileName, int severity, int start) {
+ int id = pb.getID();
+ if (CompletionEngine.this.actualCompletionPosition > start
+ && this.lastErrorStart < start
+ && pb.isError()
+ && (id & IProblem.Syntax) == 0
+ && (CompletionEngine.this.fileName == null || CharOperation.equals(CompletionEngine.this.fileName, originatingFileName))) {
+
+ CompletionEngine.this.problem = pb;
+ this.lastErrorStart = start;
+ }
+ if (this.checkProblems && !this.hasForbiddenProblems) {
+ switch (id) {
+ case IProblem.UsingDeprecatedType:
+ this.hasForbiddenProblems =
+ CompletionEngine.this.options.checkDeprecation;
+ break;
+ case IProblem.NotVisibleType:
+ this.hasForbiddenProblems =
+ CompletionEngine.this.options.checkVisibility;
+ break;
+ case IProblem.ForbiddenReference:
+ this.hasForbiddenProblems =
+ CompletionEngine.this.options.checkForbiddenReference;
+ break;
+ case IProblem.DiscouragedReference:
+ this.hasForbiddenProblems =
+ CompletionEngine.this.options.checkDiscouragedReference;
+ break;
+ default:
+ if ((severity & ProblemSeverities.Optional) != 0) {
+ this.hasAllowedProblems = true;
+ } else {
+ this.hasForbiddenProblems = true;
+ }
+
+ break;
+ }
+ }
+
+ return pb;
+ }
+
+ public CategorizedProblem createProblem(
+ char[] originatingFileName,
+ int problemId,
+ String[] problemArguments,
+ int elaborationId,
+ String[] messageArguments,
+ int severity,
+ int start,
+ int end,
+ int lineNumber,
+ int columnNumber) {
+ return checkProblem(
+ super.createProblem(
+ originatingFileName,
+ problemId,
+ problemArguments,
+ elaborationId,
+ messageArguments,
+ severity,
+ start,
+ end,
+ lineNumber,
+ columnNumber), originatingFileName, severity, start);
+ }
+
+ public CategorizedProblem createProblem(
+ char[] originatingFileName,
+ int problemId,
+ String[] problemArguments,
+ String[] messageArguments,
+ int severity,
+ int start,
+ int end,
+ int lineNumber,
+ int columnNumber) {
+ return checkProblem(
+ super.createProblem(
+ originatingFileName,
+ problemId,
+ problemArguments,
+ messageArguments,
+ severity,
+ start,
+ end,
+ lineNumber,
+ columnNumber), originatingFileName, severity, start);
+ }
+
+ public void startCheckingProblems() {
+ this.checkProblems = true;
+ this.hasForbiddenProblems = false;
+ this.hasAllowedProblems = false;
+ }
+
+ public void stopCheckingProblems() {
+ this.checkProblems = false;
+ }
+ }
+
+//{ObjectTeams: prefixes for callout-to-field:
+ private static final char[] SET = "set".toCharArray(); //$NON-NLS-1$
+
+ private static final char[] GET = "get".toCharArray(); //$NON-NLS-1$
+// SH}
+
+ public static char[] createBindingKey(char[] packageName, char[] typeName) {
+ char[] signature = createTypeSignature(packageName, typeName);
+ CharOperation.replace(signature, '.', '/');
+ return signature;
+ }
+
+ public static char[][] createDefaultParameterNames(int length) {
+ char[][] parameters;
+ switch (length) {
+ case 0 :
+ parameters = new char[length][];
+ break;
+ case 1 :
+ parameters = ARGS1;
+ break;
+ case 2 :
+ parameters = ARGS2;
+ break;
+ case 3 :
+ parameters = ARGS3;
+ break;
+ case 4 :
+ parameters = ARGS4;
+ break;
+ default :
+ parameters = new char[length][];
+ for (int i = 0; i < length; i++) {
+ parameters[i] = CharOperation.concat(ARG, String.valueOf(i).toCharArray());
+ }
+ break;
+ }
+ return parameters;
+ }
+ public static char[] createMethodSignature(char[][] parameterPackageNames, char[][] parameterTypeNames, char[] returnTypeSignature) {
+ char[][] parameterTypeSignature = new char[parameterTypeNames.length][];
+ for (int i = 0; i < parameterTypeSignature.length; i++) {
+ parameterTypeSignature[i] =
+ Signature.createCharArrayTypeSignature(
+ CharOperation.concat(
+ parameterPackageNames[i],
+ CharOperation.replaceOnCopy(parameterTypeNames[i], '.', '$'), '.'), true);
+ }
+
+ return Signature.createMethodSignature(
+ parameterTypeSignature,
+ returnTypeSignature);
+ }
+
+ public static char[] createMethodSignature(char[][] parameterPackageNames, char[][] parameterTypeNames, char[] returnPackagename, char[] returnTypeName) {
+ char[] returnTypeSignature =
+ returnTypeName == null || returnTypeName.length == 0
+ ? Signature.createCharArrayTypeSignature(VOID, true)
+ : Signature.createCharArrayTypeSignature(
+ CharOperation.concat(
+ returnPackagename,
+ CharOperation.replaceOnCopy(returnTypeName, '.', '$'), '.'), true);
+
+ return createMethodSignature(
+ parameterPackageNames,
+ parameterTypeNames,
+ returnTypeSignature);
+ }
+ public static char[] createNonGenericTypeSignature(char[] qualifiedPackageName, char[] qualifiedTypeName) {
+ return Signature.createCharArrayTypeSignature(
+ CharOperation.concat(
+ qualifiedPackageName,
+ CharOperation.replaceOnCopy(qualifiedTypeName, '.', '$'), '.'), true);
+ }
+
+ public static char[] createTypeSignature(char[] qualifiedPackageName, char[] qualifiedTypeName) {
+ char[] name = new char[qualifiedTypeName.length];
+ System.arraycopy(qualifiedTypeName, 0, name, 0, qualifiedTypeName.length);
+
+ int depth = 0;
+ int length = name.length;
+ for (int i = length -1; i >= 0; i--) {
+ switch (name[i]) {
+ case '.':
+ if (depth == 0 && name[i - 1] != '>') {
+ name[i] = '$';
+ }
+ break;
+ case '<':
+ depth--;
+ break;
+ case '>':
+ depth++;
+ break;
+ }
+ }
+ return Signature.createCharArrayTypeSignature(
+ CharOperation.concat(
+ qualifiedPackageName,
+ name, '.'), true);
+ }
+
+ private static char[] getRequiredTypeSignature(TypeBinding typeBinding) {
+ char[] result = null;
+ StringBuffer sig = new StringBuffer(10);
+
+ sig.append(typeBinding.signature());
+
+ int sigLength = sig.length();
+ result = new char[sigLength];
+ sig.getChars(0, sigLength, result, 0);
+ result = CharOperation.replaceOnCopy(result, '/', '.');
+ return result;
+ }
+
+ private static char[] getTypeName(TypeReference typeReference) {
+ char[] typeName = CharOperation.concatWith(typeReference.getTypeName(), '.');
+ int dims = typeReference.dimensions();
+ if (dims > 0) {
+ int length = typeName.length;
+ int newLength = length + (dims*2);
+ System.arraycopy(typeName, 0, typeName = new char[newLength], 0, length);
+ for (int k = length; k < newLength; k += 2) {
+ typeName[k] = '[';
+ typeName[k+1] = ']';
+ }
+ }
+
+ return typeName;
+ }
+
+ private static boolean hasStaticMemberTypes(ReferenceBinding typeBinding, SourceTypeBinding invocationType, CompilationUnitScope unitScope) {
+ ReferenceBinding[] memberTypes = typeBinding.memberTypes();
+ int length = memberTypes == null ? 0 : memberTypes.length;
+ next : for (int i = 0; i < length; i++) {
+ ReferenceBinding memberType = memberTypes[i];
+ if (invocationType != null && !memberType.canBeSeenBy(typeBinding, invocationType)) {
+ continue next;
+ } else if(invocationType == null && !memberType.canBeSeenBy(unitScope.fPackage)) {
+ continue next;
+ }
+
+ if ((memberType.modifiers & ClassFileConstants.AccStatic) != 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static boolean hasMemberTypesInEnclosingScope(SourceTypeBinding typeBinding, Scope scope) {
+ ReferenceBinding[] memberTypes = typeBinding.memberTypes();
+ int length = memberTypes == null ? 0 : memberTypes.length;
+
+ if (length > 0) {
+ MethodScope methodScope = scope.methodScope();
+ if (methodScope != null && !methodScope.isStatic) {
+ ClassScope classScope = typeBinding.scope;
+ Scope currentScope = scope;
+ while (currentScope != null) {
+ if (currentScope == classScope) {
+ return true;
+ }
+ currentScope = currentScope.parent;
+ }
+ }
+ }
+ return false;
+ }
+
+ public HashtableOfObject typeCache;
+ public int openedBinaryTypes; // used during InternalCompletionProposal#findConstructorParameterNames()
+
+ public static boolean DEBUG = false;
+ public static boolean PERF = false;
+
+ private static final char[] KNOWN_TYPE_WITH_UNKNOWN_CONSTRUCTORS = new char[]{};
+ private static final char[] KNOWN_TYPE_WITH_KNOWN_CONSTRUCTORS = new char[]{};
+
+ private static final char[] ARG = "arg".toCharArray(); //$NON-NLS-1$
+ private static final char[] ARG0 = "arg0".toCharArray(); //$NON-NLS-1$
+ private static final char[] ARG1 = "arg1".toCharArray(); //$NON-NLS-1$
+ private static final char[] ARG2 = "arg2".toCharArray(); //$NON-NLS-1$
+ private static final char[] ARG3 = "arg3".toCharArray(); //$NON-NLS-1$
+ private static final char[][] ARGS1 = new char[][]{ARG0};
+ private static final char[][] ARGS2 = new char[][]{ARG0, ARG1};
+ private static final char[][] ARGS3 = new char[][]{ARG0, ARG1, ARG2};
+ private static final char[][] ARGS4 = new char[][]{ARG0, ARG1, ARG2, ARG3};
+
+ private final static int CHECK_CANCEL_FREQUENCY = 50;
+
+ // temporary constants to quickly disabled polish features if necessary
+ public final static boolean NO_TYPE_COMPLETION_ON_EMPTY_TOKEN = false;
+
+ private final static char[] ERROR_PATTERN = "*error*".toCharArray(); //$NON-NLS-1$
+ private final static char[] EXCEPTION_PATTERN = "*exception*".toCharArray(); //$NON-NLS-1$
+ private final static char[] SEMICOLON = new char[] { ';' };
+
+ private final static char[] CLASS = "Class".toCharArray(); //$NON-NLS-1$
+ private final static char[] VOID = "void".toCharArray(); //$NON-NLS-1$
+ private final static char[] INT = "int".toCharArray(); //$NON-NLS-1$
+ private final static char[] INT_SIGNATURE = new char[]{Signature.C_INT};
+ private final static char[] VALUE = "value".toCharArray(); //$NON-NLS-1$
+ private final static char[] EXTENDS = "extends".toCharArray(); //$NON-NLS-1$
+ private final static char[] SUPER = "super".toCharArray(); //$NON-NLS-1$
+//{ObjectTeams: for <B base R>
+ private final static char[] BASE = "base".toCharArray(); //$NON-NLS-1$
+// SH}
+ private final static char[] DEFAULT_CONSTRUCTOR_SIGNATURE = "()V".toCharArray(); //$NON-NLS-1$
+
+ private final static char[] DOT = ".".toCharArray(); //$NON-NLS-1$
+
+ private final static char[] VARARGS = "...".toCharArray(); //$NON-NLS-1$
+
+ private final static char[] IMPORT = "import".toCharArray(); //$NON-NLS-1$
+ private final static char[] STATIC = "static".toCharArray(); //$NON-NLS-1$
+ private final static char[] ON_DEMAND = ".*".toCharArray(); //$NON-NLS-1$
+ private final static char[] IMPORT_END = ";\n".toCharArray(); //$NON-NLS-1$
+
+ private final static char[] JAVA_LANG_OBJECT_SIGNATURE =
+ createTypeSignature(CharOperation.concatWith(JAVA_LANG, '.'), OBJECT);
+ private final static char[] JAVA_LANG_NAME =
+ CharOperation.concatWith(JAVA_LANG, '.');
+
+ private final static int NONE = 0;
+ private final static int SUPERTYPE = 1;
+ private final static int SUBTYPE = 2;
+
+ int expectedTypesPtr = -1;
+ TypeBinding[] expectedTypes = new TypeBinding[1];
+ int expectedTypesFilter;
+ boolean hasJavaLangObjectAsExpectedType = false;
+ boolean hasExpectedArrayTypes = false;
+ boolean hasComputedExpectedArrayTypes = false;
+ int uninterestingBindingsPtr = -1;
+ Binding[] uninterestingBindings = new Binding[1];
+ int forbbidenBindingsPtr = -1;
+ Binding[] forbbidenBindings = new Binding[1];
+ int forbbidenBindingsFilter;
+
+ ImportBinding[] favoriteReferenceBindings;
+
+ boolean assistNodeIsClass;
+ boolean assistNodeIsEnum;
+ boolean assistNodeIsException;
+ boolean assistNodeIsInterface;
+ boolean assistNodeIsAnnotation;
+ boolean assistNodeIsConstructor;
+ boolean assistNodeIsSuperType;
+ boolean assistNodeIsExtendedType;
+ int assistNodeInJavadoc = 0;
+ boolean assistNodeCanBeSingleMemberAnnotation = false;
+
+ long targetedElement;
+//{ObjectTeams:
+ private AbstractMethodMappingDeclaration currentMethodMapping;
+ private char seperator= 0; // char that should be inserted before the completion
+ // searching candidates for callin/callout: are we searching the base class's super?
+ private static final int SEARCH_SUPER_BASE = 0x1000; // must be larger than CompletionProposal.LAST_KIND
+// SH}
+ WorkingCopyOwner owner;
+ IProgressMonitor monitor;
+ IJavaProject javaProject;
+ ITypeRoot typeRoot;
+ CompletionParser parser;
+ CompletionRequestor requestor;
+ CompletionProblemFactory problemFactory;
+ ProblemReporter problemReporter;
+ private JavaSearchNameEnvironment noCacheNameEnvironment;
+ char[] source;
+ char[] completionToken;
+ char[] qualifiedCompletionToken;
+ boolean resolvingImports = false;
+ boolean resolvingStaticImports = false;
+ boolean insideQualifiedReference = false;
+ boolean noProposal = true;
+ CategorizedProblem problem = null;
+ char[] fileName = null;
+ int startPosition, actualCompletionPosition, endPosition, offset;
+ int tokenStart, tokenEnd;
+ int javadocTagPosition; // Position of previous tag while completing in javadoc
+ HashtableOfObject knownPkgs = new HashtableOfObject(10);
+ HashtableOfObject knownTypes = new HashtableOfObject(10);
+
+ /*
+ static final char[][] mainDeclarations =
+ new char[][] {
+ "package".toCharArray(),
+ "import".toCharArray(),
+ "abstract".toCharArray(),
+ "final".toCharArray(),
+ "public".toCharArray(),
+ "class".toCharArray(),
+ "interface".toCharArray()};
+
+ static final char[][] modifiers = // may want field, method, type & member type modifiers
+ new char[][] {
+ "abstract".toCharArray(),
+ "final".toCharArray(),
+ "native".toCharArray(),
+ "public".toCharArray(),
+ "protected".toCharArray(),
+ "private".toCharArray(),
+ "static".toCharArray(),
+ "strictfp".toCharArray(),
+ "synchronized".toCharArray(),
+ "transient".toCharArray(),
+ "volatile".toCharArray()};
+ */
+ static final BaseTypeBinding[] BASE_TYPES = {
+ TypeBinding.BOOLEAN,
+ TypeBinding.BYTE,
+ TypeBinding.CHAR,
+ TypeBinding.DOUBLE,
+ TypeBinding.FLOAT,
+ TypeBinding.INT,
+ TypeBinding.LONG,
+ TypeBinding.SHORT,
+ TypeBinding.VOID
+ };
+ static final int BASE_TYPES_LENGTH = BASE_TYPES.length;
+ static final char[][] BASE_TYPE_NAMES = new char[BASE_TYPES_LENGTH][];
+ static final int BASE_TYPES_WITHOUT_VOID_LENGTH = BASE_TYPES.length - 1;
+ static final char[][] BASE_TYPE_NAMES_WITHOUT_VOID = new char[BASE_TYPES_WITHOUT_VOID_LENGTH][];
+ static {
+ for (int i=0; i<BASE_TYPES_LENGTH; i++) {
+ BASE_TYPE_NAMES[i] = BASE_TYPES[i].simpleName;
+ }
+ for (int i=0; i<BASE_TYPES_WITHOUT_VOID_LENGTH; i++) {
+ BASE_TYPE_NAMES_WITHOUT_VOID[i] = BASE_TYPES[i].simpleName;
+ }
+ }
+
+ static final char[] classField = "class".toCharArray(); //$NON-NLS-1$
+ static final char[] lengthField = "length".toCharArray(); //$NON-NLS-1$
+ static final char[] cloneMethod = "clone".toCharArray(); //$NON-NLS-1$
+ static final char[] THIS = "this".toCharArray(); //$NON-NLS-1$
+ static final char[] THROWS = "throws".toCharArray(); //$NON-NLS-1$
+
+ static InvocationSite FakeInvocationSite = new InvocationSite(){
+ public TypeBinding[] genericTypeArguments() { return null; }
+ public boolean isSuperAccess(){ return false; }
+ public boolean isTypeAccess(){ return false; }
+ public void setActualReceiverType(ReferenceBinding receiverType) {/* empty */}
+ public void setDepth(int depth){/* empty */}
+ public void setFieldIndex(int depth){/* empty */}
+ public int sourceEnd() { return 0; }
+ public int sourceStart() { return 0; }
+ };
+
+ private int foundTypesCount;
+ private ObjectVector acceptedTypes;
+
+ private int foundConstructorsCount;
+ private ObjectVector acceptedConstructors;
+
+ /**
+ * The CompletionEngine is responsible for computing source completions.
+ *
+ * It requires a searchable name environment, which supports some
+ * specific search APIs, and a requestor to feed back the results to a UI.
+ *
+ * @param nameEnvironment org.eclipse.jdt.internal.codeassist.ISearchableNameEnvironment
+ * used to resolve type/package references and search for types/packages
+ * based on partial names.
+ *
+ * @param requestor org.eclipse.jdt.internal.codeassist.ICompletionRequestor
+ * since the engine might produce answers of various forms, the engine
+ * is associated with a requestor able to accept all possible completions.
+ *
+ * @param settings java.util.Map
+ * set of options used to configure the code assist engine.
+ */
+ public CompletionEngine(
+ SearchableEnvironment nameEnvironment,
+ CompletionRequestor requestor,
+ Map settings,
+ IJavaProject javaProject,
+ WorkingCopyOwner owner,
+ IProgressMonitor monitor) {
+ super(settings);
+ this.javaProject = javaProject;
+ this.requestor = requestor;
+ this.nameEnvironment = nameEnvironment;
+ this.typeCache = new HashtableOfObject(5);
+ this.openedBinaryTypes = 0;
+
+ this.problemFactory = new CompletionProblemFactory(Locale.getDefault());
+ this.problemReporter = new ProblemReporter(
+ DefaultErrorHandlingPolicies.proceedWithAllProblems(),
+ this.compilerOptions,
+ this.problemFactory);
+ this.lookupEnvironment =
+ new LookupEnvironment(this, this.compilerOptions, this.problemReporter, nameEnvironment);
+ this.parser =
+ new CompletionParser(this.problemReporter, this.requestor.isExtendedContextRequired());
+ this.owner = owner;
+ this.monitor = monitor;
+ }
+
+ public void acceptConstructor(
+ int modifiers,
+ char[] simpleTypeName,
+ int parameterCount,
+ char[] signature,
+ char[][] parameterTypes,
+ char[][] parameterNames,
+ int typeModifiers,
+ char[] packageName,
+ int extraFlags,
+ String path,
+ AccessRestriction accessRestriction) {
+
+ // does not check cancellation for every types to avoid performance loss
+ if ((this.foundConstructorsCount % (CHECK_CANCEL_FREQUENCY)) == 0) checkCancel();
+ this.foundConstructorsCount++;
+
+ if ((typeModifiers & ClassFileConstants.AccEnum) != 0) return;
+
+ if (this.options.checkDeprecation && (typeModifiers & ClassFileConstants.AccDeprecated) != 0) return;
+
+ if (this.options.checkVisibility) {
+ if((typeModifiers & ClassFileConstants.AccPublic) == 0) {
+ if((typeModifiers & ClassFileConstants.AccPrivate) != 0) return;
+
+ if (this.currentPackageName == null) {
+ initializePackageCache();
+ }
+
+ if(!CharOperation.equals(packageName, this.currentPackageName)) return;
+ }
+ }
+
+ int accessibility = IAccessRule.K_ACCESSIBLE;
+ if(accessRestriction != null) {
+ switch (accessRestriction.getProblemId()) {
+ case IProblem.ForbiddenReference:
+ if (this.options.checkForbiddenReference) {
+ return;
+ }
+ accessibility = IAccessRule.K_NON_ACCESSIBLE;
+ break;
+ case IProblem.DiscouragedReference:
+ if (this.options.checkDiscouragedReference) {
+ return;
+ }
+ accessibility = IAccessRule.K_DISCOURAGED;
+ break;
+ }
+ }
+
+ if(this.acceptedConstructors == null) {
+ this.acceptedConstructors = new ObjectVector();
+ }
+ this.acceptedConstructors.add(
+ new AcceptedConstructor(
+ modifiers,
+ simpleTypeName,
+ parameterCount,
+ signature,
+ parameterTypes,
+ parameterNames,
+ typeModifiers,
+ packageName,
+ extraFlags,
+ accessibility));
+ }
+
+ private void acceptConstructors(Scope scope) {
+ final boolean DEFER_QUALIFIED_PROPOSALS = false;
+
+ this.checkCancel();
+
+ if(this.acceptedConstructors == null) return;
+
+ int length = this.acceptedConstructors.size();
+
+ if(length == 0) return;
+
+ HashtableOfObject onDemandFound = new HashtableOfObject();
+
+ ArrayList deferredProposals = null;
+ if (DEFER_QUALIFIED_PROPOSALS) {
+ deferredProposals = new ArrayList();
+ }
+
+ try {
+ next : for (int i = 0; i < length; i++) {
+
+ // does not check cancellation for every types to avoid performance loss
+ if ((i % CHECK_CANCEL_FREQUENCY) == 0) checkCancel();
+
+ AcceptedConstructor acceptedConstructor = (AcceptedConstructor)this.acceptedConstructors.elementAt(i);
+ final int typeModifiers = acceptedConstructor.typeModifiers;
+ final char[] packageName = acceptedConstructor.packageName;
+ final char[] simpleTypeName = acceptedConstructor.simpleTypeName;
+ final int modifiers = acceptedConstructor.modifiers;
+ final int parameterCount = acceptedConstructor.parameterCount;
+ final char[] signature = acceptedConstructor.signature;
+ final char[][] parameterTypes = acceptedConstructor.parameterTypes;
+ final char[][] parameterNames = acceptedConstructor.parameterNames;
+ final int extraFlags = acceptedConstructor.extraFlags;
+ final int accessibility = acceptedConstructor.accessibility;
+
+ boolean proposeType = hasArrayTypeAsExpectedSuperTypes() || (extraFlags & ExtraFlags.HasNonPrivateStaticMemberTypes) != 0;
+
+ char[] fullyQualifiedName = CharOperation.concat(packageName, simpleTypeName, '.');
+
+ Object knownTypeKind = this.knownTypes.get(fullyQualifiedName);
+ if (knownTypeKind != null) {
+ if (knownTypeKind == KNOWN_TYPE_WITH_KNOWN_CONSTRUCTORS) {
+ // the type and its constructors are already accepted
+ continue next;
+ }
+ // this type is already accepted
+ proposeType = false;
+ } else {
+ this.knownTypes.put(fullyQualifiedName, KNOWN_TYPE_WITH_UNKNOWN_CONSTRUCTORS);
+ }
+
+ boolean proposeConstructor = true;
+
+ if (this.options.checkVisibility) {
+ if((modifiers & ClassFileConstants.AccPublic) == 0) {
+ if((modifiers & ClassFileConstants.AccPrivate) != 0) {
+ if (!proposeType) continue next;
+ proposeConstructor = false;
+ } else {
+ if (this.currentPackageName == null) {
+ initializePackageCache();
+ }
+
+ if(!CharOperation.equals(packageName, this.currentPackageName)) {
+
+ if((typeModifiers & ClassFileConstants.AccAbstract) == 0 ||
+ (modifiers & ClassFileConstants.AccProtected) == 0) {
+ if (!proposeType) continue next;
+ proposeConstructor = false;
+ }
+ }
+ }
+ }
+ }
+
+ acceptedConstructor.fullyQualifiedName = fullyQualifiedName;
+ acceptedConstructor.proposeType = proposeType;
+ acceptedConstructor.proposeConstructor = proposeConstructor;
+
+
+ if(!this.importCachesInitialized) {
+ initializeImportCaches();
+ }
+
+ for (int j = 0; j < this.importCacheCount; j++) {
+ char[][] importName = this.importsCache[j];
+ if(CharOperation.equals(simpleTypeName, importName[0])) {
+ if (proposeType) {
+ proposeType(
+ packageName,
+ simpleTypeName,
+ typeModifiers,
+ accessibility,
+ simpleTypeName,
+ fullyQualifiedName,
+ !CharOperation.equals(fullyQualifiedName, importName[1]),
+ scope);
+ }
+
+ if (proposeConstructor && !Flags.isEnum(typeModifiers)) {
+ boolean isQualified = !CharOperation.equals(fullyQualifiedName, importName[1]);
+ if (!isQualified) {
+ proposeConstructor(
+ simpleTypeName,
+ parameterCount,
+ signature,
+ parameterTypes,
+ parameterNames,
+ modifiers,
+ packageName,
+ typeModifiers,
+ accessibility,
+ simpleTypeName,
+ fullyQualifiedName,
+ isQualified,
+ scope,
+ extraFlags);
+ } else {
+ acceptedConstructor.mustBeQualified = true;
+ if (DEFER_QUALIFIED_PROPOSALS) {
+ deferredProposals.add(acceptedConstructor);
+ } else {
+ proposeConstructor(acceptedConstructor, scope);
+ }
+ }
+ }
+ continue next;
+ }
+ }
+
+
+ if (CharOperation.equals(this.currentPackageName, packageName)) {
+ if (proposeType) {
+ proposeType(
+ packageName,
+ simpleTypeName,
+ typeModifiers,
+ accessibility,
+ simpleTypeName,
+ fullyQualifiedName,
+ false,
+ scope);
+ }
+
+ if (proposeConstructor && !Flags.isEnum(typeModifiers)) {
+ proposeConstructor(
+ simpleTypeName,
+ parameterCount,
+ signature,
+ parameterTypes,
+ parameterNames,
+ modifiers,
+ packageName,
+ typeModifiers,
+ accessibility,
+ simpleTypeName,
+ fullyQualifiedName,
+ false,
+ scope,
+ extraFlags);
+ }
+ continue next;
+ } else {
+ char[] fullyQualifiedEnclosingTypeOrPackageName = null;
+
+ AcceptedConstructor foundConstructor = null;
+ if((foundConstructor = (AcceptedConstructor)onDemandFound.get(simpleTypeName)) == null) {
+ for (int j = 0; j < this.onDemandImportCacheCount; j++) {
+ ImportBinding importBinding = this.onDemandImportsCache[j];
+
+ char[][] importName = importBinding.compoundName;
+ char[] importFlatName = CharOperation.concatWith(importName, '.');
+
+ if(fullyQualifiedEnclosingTypeOrPackageName == null) {
+ fullyQualifiedEnclosingTypeOrPackageName = packageName;
+ }
+ if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
+ if(importBinding.isStatic()) {
+ if((typeModifiers & ClassFileConstants.AccStatic) != 0) {
+ onDemandFound.put(
+ simpleTypeName,
+ acceptedConstructor);
+ continue next;
+ }
+ } else {
+ onDemandFound.put(
+ simpleTypeName,
+ acceptedConstructor);
+ continue next;
+ }
+ }
+ }
+ } else if(!foundConstructor.mustBeQualified){
+ done : for (int j = 0; j < this.onDemandImportCacheCount; j++) {
+ ImportBinding importBinding = this.onDemandImportsCache[j];
+
+ char[][] importName = importBinding.compoundName;
+ char[] importFlatName = CharOperation.concatWith(importName, '.');
+
+ if(fullyQualifiedEnclosingTypeOrPackageName == null) {
+ fullyQualifiedEnclosingTypeOrPackageName = packageName;
+ }
+ if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
+ if(importBinding.isStatic()) {
+ if((typeModifiers & ClassFileConstants.AccStatic) != 0) {
+ foundConstructor.mustBeQualified = true;
+ break done;
+ }
+ } else {
+ foundConstructor.mustBeQualified = true;
+ break done;
+ }
+ }
+ }
+ }
+ if (proposeType) {
+ proposeType(
+ packageName,
+ simpleTypeName,
+ typeModifiers,
+ accessibility,
+ simpleTypeName,
+ fullyQualifiedName,
+ true,
+ scope);
+ }
+
+ if (proposeConstructor && !Flags.isEnum(typeModifiers)) {
+ acceptedConstructor.mustBeQualified = true;
+ if (DEFER_QUALIFIED_PROPOSALS) {
+ deferredProposals.add(acceptedConstructor);
+ } else {
+ proposeConstructor(acceptedConstructor, scope);
+ }
+ }
+ }
+ }
+
+ char[][] keys = onDemandFound.keyTable;
+ Object[] values = onDemandFound.valueTable;
+ int max = keys.length;
+ for (int i = 0; i < max; i++) {
+
+ // does not check cancellation for every types to avoid performance loss
+ if ((i % CHECK_CANCEL_FREQUENCY) == 0) checkCancel();
+
+ if(keys[i] != null) {
+ AcceptedConstructor value = (AcceptedConstructor) values[i];
+ if(value != null) {
+ if (value.proposeType) {
+ proposeType(
+ value.packageName,
+ value.simpleTypeName,
+ value.typeModifiers,
+ value.accessibility,
+ value.simpleTypeName,
+ value.fullyQualifiedName,
+ value.mustBeQualified,
+ scope);
+ }
+
+ if (value.proposeConstructor && !Flags.isEnum(value.modifiers)) {
+ if (!value.mustBeQualified) {
+ proposeConstructor(
+ value.simpleTypeName,
+ value.parameterCount,
+ value.signature,
+ value.parameterTypes,
+ value.parameterNames,
+ value.modifiers,
+ value.packageName,
+ value.typeModifiers,
+ value.accessibility,
+ value.simpleTypeName,
+ value.fullyQualifiedName,
+ value.mustBeQualified,
+ scope,
+ value.extraFlags);
+ } else {
+ if (DEFER_QUALIFIED_PROPOSALS) {
+ deferredProposals.add(value);
+ } else {
+ proposeConstructor(value, scope);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (DEFER_QUALIFIED_PROPOSALS) {
+ int size = deferredProposals.size();
+ for (int i = 0; i < size; i++) {
+
+ // does not check cancellation for every types to avoid performance loss
+ if ((i % CHECK_CANCEL_FREQUENCY) == 0) checkCancel();
+
+ AcceptedConstructor deferredProposal = (AcceptedConstructor)deferredProposals.get(i);
+
+ if (deferredProposal.proposeConstructor) {
+ proposeConstructor(
+ deferredProposal.simpleTypeName,
+ deferredProposal.parameterCount,
+ deferredProposal.signature,
+ deferredProposal.parameterTypes,
+ deferredProposal.parameterNames,
+ deferredProposal.modifiers,
+ deferredProposal.packageName,
+ deferredProposal.typeModifiers,
+ deferredProposal.accessibility,
+ deferredProposal.simpleTypeName,
+ deferredProposal.fullyQualifiedName,
+ deferredProposal.mustBeQualified,
+ scope,
+ deferredProposal.extraFlags);
+ }
+ }
+ }
+ } finally {
+ this.acceptedTypes = null; // reset
+ }
+ }
+
+ /**
+ * One result of the search consists of a new package.
+ *
+ * NOTE - All package names are presented in their readable form:
+ * Package names are in the form "a.b.c".
+ * The default package is represented by an empty array.
+ */
+ public void acceptPackage(char[] packageName) {
+
+ if (this.knownPkgs.containsKey(packageName)) return;
+
+ this.knownPkgs.put(packageName, this);
+
+ char[] completion;
+ if(this.resolvingImports) {
+ if(this.resolvingStaticImports) {
+ completion = CharOperation.concat(packageName, new char[] { '.' });
+ } else {
+ completion = CharOperation.concat(packageName, new char[] { '.', '*', ';' });
+ }
+ } else {
+ completion = packageName;
+ }
+
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForCaseMatching(this.qualifiedCompletionToken == null ? this.completionToken : this.qualifiedCompletionToken, packageName);
+ if(!this.resolvingImports) {
+ relevance += computeRelevanceForQualification(true);
+ }
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+
+ this.noProposal = false;
+ if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.PACKAGE_REF, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(packageName);
+ proposal.setPackageName(packageName);
+ proposal.setCompletion(completion);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ }
+
+ /**
+ * One result of the search consists of a new type.
+ *
+ * NOTE - All package and type names are presented in their readable form:
+ * Package names are in the form "a.b.c".
+ * Nested type names are in the qualified form "A.I".
+ * The default package is represented by an empty array.
+ */
+ public void acceptType(
+ char[] packageName,
+ char[] simpleTypeName,
+ char[][] enclosingTypeNames,
+ int modifiers,
+ AccessRestriction accessRestriction) {
+
+ // does not check cancellation for every types to avoid performance loss
+ if ((this.foundTypesCount % CHECK_CANCEL_FREQUENCY) == 0) checkCancel();
+ this.foundTypesCount++;
+
+ if (this.options.checkDeprecation && (modifiers & ClassFileConstants.AccDeprecated) != 0) return;
+ if (this.assistNodeIsExtendedType && (modifiers & ClassFileConstants.AccFinal) != 0) return;
+
+ if (this.options.checkVisibility) {
+ if((modifiers & ClassFileConstants.AccPublic) == 0) {
+ if((modifiers & ClassFileConstants.AccPrivate) != 0) return;
+
+ char[] currentPackage = CharOperation.concatWith(this.unitScope.fPackage.compoundName, '.');
+ if(!CharOperation.equals(packageName, currentPackage)) return;
+ }
+ }
+
+ int accessibility = IAccessRule.K_ACCESSIBLE;
+ if(accessRestriction != null) {
+ switch (accessRestriction.getProblemId()) {
+ case IProblem.ForbiddenReference:
+ if (this.options.checkForbiddenReference) {
+ return;
+ }
+ accessibility = IAccessRule.K_NON_ACCESSIBLE;
+ break;
+ case IProblem.DiscouragedReference:
+ if (this.options.checkDiscouragedReference) {
+ return;
+ }
+ accessibility = IAccessRule.K_DISCOURAGED;
+ break;
+ }
+ }
+
+ if (isForbiddenType(packageName, simpleTypeName, enclosingTypeNames)) {
+ return;
+ }
+
+ if(this.acceptedTypes == null) {
+ this.acceptedTypes = new ObjectVector();
+ }
+ this.acceptedTypes.add(new AcceptedType(packageName, simpleTypeName, enclosingTypeNames, modifiers, accessibility));
+ }
+
+ private void acceptTypes(Scope scope) {
+ this.checkCancel();
+
+ if(this.acceptedTypes == null) return;
+
+ int length = this.acceptedTypes.size();
+
+ if(length == 0) return;
+
+ HashtableOfObject onDemandFound = new HashtableOfObject();
+
+ try {
+ next : for (int i = 0; i < length; i++) {
+
+ // does not check cancellation for every types to avoid performance loss
+ if ((i % CHECK_CANCEL_FREQUENCY) == 0) checkCancel();
+
+ AcceptedType acceptedType = (AcceptedType)this.acceptedTypes.elementAt(i);
+ char[] packageName = acceptedType.packageName;
+ char[] simpleTypeName = acceptedType.simpleTypeName;
+ char[][] enclosingTypeNames = acceptedType.enclosingTypeNames;
+ int modifiers = acceptedType.modifiers;
+ int accessibility = acceptedType.accessibility;
+
+ char[] typeName;
+ char[] flatEnclosingTypeNames;
+ if(enclosingTypeNames == null || enclosingTypeNames.length == 0) {
+ flatEnclosingTypeNames = null;
+ typeName = simpleTypeName;
+ } else {
+ flatEnclosingTypeNames = CharOperation.concatWith(acceptedType.enclosingTypeNames, '.');
+ typeName = CharOperation.concat(flatEnclosingTypeNames, simpleTypeName, '.');
+ }
+ char[] fullyQualifiedName = CharOperation.concat(packageName, typeName, '.');
+
+ if (this.knownTypes.containsKey(fullyQualifiedName)) continue next;
+
+ this.knownTypes.put(fullyQualifiedName, KNOWN_TYPE_WITH_UNKNOWN_CONSTRUCTORS);
+
+ if (this.resolvingImports) {
+ if(this.compilerOptions.complianceLevel >= ClassFileConstants.JDK1_4 && packageName.length == 0) {
+ continue next; // import of default package is forbidden when compliance is 1.4 or higher
+ }
+
+ char[] completionName = this.insideQualifiedReference ? simpleTypeName : fullyQualifiedName;
+
+ if(this.resolvingStaticImports) {
+ if(enclosingTypeNames == null || enclosingTypeNames.length == 0) {
+ completionName = CharOperation.concat(completionName, new char[] { '.' });
+ } else if ((modifiers & ClassFileConstants.AccStatic) == 0) {
+ continue next;
+ } else {
+ completionName = CharOperation.concat(completionName, new char[] { ';' });
+ }
+ } else {
+ completionName = CharOperation.concat(completionName, new char[] { ';' });
+ }
+
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForRestrictions(accessibility);
+ relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName);
+
+ this.noProposal = false;
+ if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+ createTypeProposal(packageName, typeName, modifiers, accessibility, completionName, relevance);
+ }
+ } else {
+ if(!this.importCachesInitialized) {
+ initializeImportCaches();
+ }
+
+ for (int j = 0; j < this.importCacheCount; j++) {
+ char[][] importName = this.importsCache[j];
+ if(CharOperation.equals(typeName, importName[0])) {
+ proposeType(
+ packageName,
+ simpleTypeName,
+ modifiers,
+ accessibility,
+ typeName,
+ fullyQualifiedName,
+ !CharOperation.equals(fullyQualifiedName, importName[1]),
+ scope);
+ continue next;
+ }
+ }
+
+
+ if ((enclosingTypeNames == null || enclosingTypeNames.length == 0 ) && CharOperation.equals(this.currentPackageName, packageName)) {
+ proposeType(
+ packageName,
+ simpleTypeName,
+ modifiers,
+ accessibility,
+ typeName,
+ fullyQualifiedName,
+ false,
+ scope);
+ continue next;
+ } else {
+ char[] fullyQualifiedEnclosingTypeOrPackageName = null;
+
+ AcceptedType foundType = null;
+ if((foundType = (AcceptedType)onDemandFound.get(simpleTypeName)) == null) {
+ for (int j = 0; j < this.onDemandImportCacheCount; j++) {
+ ImportBinding importBinding = this.onDemandImportsCache[j];
+
+ char[][] importName = importBinding.compoundName;
+ char[] importFlatName = CharOperation.concatWith(importName, '.');
+
+ if(fullyQualifiedEnclosingTypeOrPackageName == null) {
+ if(enclosingTypeNames != null && enclosingTypeNames.length != 0) {
+ fullyQualifiedEnclosingTypeOrPackageName =
+ CharOperation.concat(
+ packageName,
+ flatEnclosingTypeNames,
+ '.');
+ } else {
+ fullyQualifiedEnclosingTypeOrPackageName =
+ packageName;
+ }
+ }
+ if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
+ if(importBinding.isStatic()) {
+ if((modifiers & ClassFileConstants.AccStatic) != 0) {
+ acceptedType.qualifiedTypeName = typeName;
+ acceptedType.fullyQualifiedName = fullyQualifiedName;
+ onDemandFound.put(
+ simpleTypeName,
+ acceptedType);
+ continue next;
+ }
+ } else {
+ acceptedType.qualifiedTypeName = typeName;
+ acceptedType.fullyQualifiedName = fullyQualifiedName;
+ onDemandFound.put(
+ simpleTypeName,
+ acceptedType);
+ continue next;
+ }
+ }
+ }
+ } else if(!foundType.mustBeQualified){
+ done : for (int j = 0; j < this.onDemandImportCacheCount; j++) {
+ ImportBinding importBinding = this.onDemandImportsCache[j];
+
+ char[][] importName = importBinding.compoundName;
+ char[] importFlatName = CharOperation.concatWith(importName, '.');
+
+ if(fullyQualifiedEnclosingTypeOrPackageName == null) {
+ if(enclosingTypeNames != null && enclosingTypeNames.length != 0) {
+ fullyQualifiedEnclosingTypeOrPackageName =
+ CharOperation.concat(
+ packageName,
+ flatEnclosingTypeNames,
+ '.');
+ } else {
+ fullyQualifiedEnclosingTypeOrPackageName =
+ packageName;
+ }
+ }
+ if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
+ if(importBinding.isStatic()) {
+ if((modifiers & ClassFileConstants.AccStatic) != 0) {
+ foundType.mustBeQualified = true;
+ break done;
+ }
+ } else {
+ foundType.mustBeQualified = true;
+ break done;
+ }
+ }
+ }
+ }
+ proposeType(
+ packageName,
+ simpleTypeName,
+ modifiers,
+ accessibility,
+ typeName,
+ fullyQualifiedName,
+ true,
+ scope);
+ }
+ }
+ }
+
+ char[][] keys = onDemandFound.keyTable;
+ Object[] values = onDemandFound.valueTable;
+ int max = keys.length;
+ for (int i = 0; i < max; i++) {
+ if ((i % CHECK_CANCEL_FREQUENCY) == 0) checkCancel();
+ if(keys[i] != null) {
+ AcceptedType value = (AcceptedType) values[i];
+ if(value != null) {
+ proposeType(
+ value.packageName,
+ value.simpleTypeName,
+ value.modifiers,
+ value.accessibility,
+ value.qualifiedTypeName,
+ value.fullyQualifiedName,
+ value.mustBeQualified,
+ scope);
+ }
+ }
+ }
+ } finally {
+ this.acceptedTypes = null; // reset
+ }
+ }
+
+ public void acceptUnresolvedName(char[] name) {
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution(false);
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForCaseMatching(this.completionToken, name);
+ relevance += computeRelevanceForQualification(false);
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for local variable
+ CompletionEngine.this.noProposal = false;
+ if(!CompletionEngine.this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
+ InternalCompletionProposal proposal = CompletionEngine.this.createProposal(CompletionProposal.LOCAL_VARIABLE_REF, CompletionEngine.this.actualCompletionPosition);
+ proposal.setSignature(JAVA_LANG_OBJECT_SIGNATURE);
+ proposal.setPackageName(JAVA_LANG_NAME);
+ proposal.setTypeName(OBJECT);
+ proposal.setName(name);
+ proposal.setCompletion(name);
+ proposal.setFlags(Flags.AccDefault);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ CompletionEngine.this.requestor.accept(proposal);
+ if(DEBUG) {
+ CompletionEngine.this.printDebug(proposal);
+ }
+ }
+ }
+ private void addExpectedType(TypeBinding type, Scope scope){
+ if (type == null || !type.isValidBinding() || type == TypeBinding.NULL) return;
+
+ // do not add twice the same type
+ for (int i = 0; i <= this.expectedTypesPtr; i++) {
+ if (this.expectedTypes[i] == type) return;
+ }
+
+ int length = this.expectedTypes.length;
+ if (++this.expectedTypesPtr >= length)
+ System.arraycopy(this.expectedTypes, 0, this.expectedTypes = new TypeBinding[length * 2], 0, length);
+ this.expectedTypes[this.expectedTypesPtr] = type;
+
+ if(type == scope.getJavaLangObject()) {
+ this.hasJavaLangObjectAsExpectedType = true;
+ }
+ }
+
+ private void addForbiddenBindings(Binding binding){
+//{ObjectTeams: allow one-time recursion:
+ addForbiddenBindings(binding, 0);
+ }
+
+ private void addForbiddenBindings(Binding binding, int level){
+// SH}
+ if (binding == null) return;
+
+ int length = this.forbbidenBindings.length;
+ if (++this.forbbidenBindingsPtr >= length)
+ System.arraycopy(this.forbbidenBindings, 0, this.forbbidenBindings = new Binding[length * 2], 0, length);
+ this.forbbidenBindings[this.forbbidenBindingsPtr] = binding;
+//{ObjectTeams: other role part, too:
+ if (level == 0 && binding instanceof ReferenceBinding) {
+ ReferenceBinding type = (ReferenceBinding)binding;
+ if (type.isRole()) {
+ RoleModel role = type.roleModel;
+ ReferenceBinding otherPart = type.isClass() ? role.getInterfacePartBinding() : role.getClassPartBinding();
+ if (otherPart != null)
+ addForbiddenBindings(otherPart, 1);
+ }
+ }
+// SH}
+ }
+
+ private void addUninterestingBindings(Binding binding){
+ if (binding == null) return;
+
+ int length = this.uninterestingBindings.length;
+ if (++this.uninterestingBindingsPtr >= length)
+ System.arraycopy(this.uninterestingBindings, 0, this.uninterestingBindings = new Binding[length * 2], 0, length);
+ this.uninterestingBindings[this.uninterestingBindingsPtr] = binding;
+ }
+
+ // this code is derived from MethodBinding#areParametersCompatibleWith(TypeBinding[])
+ private final boolean areParametersCompatibleWith(TypeBinding[] parameters, TypeBinding[] arguments, boolean isVarargs) {
+ int paramLength = parameters.length;
+ int argLength = arguments.length;
+ int lastIndex = argLength;
+ if (isVarargs) {
+ lastIndex = paramLength - 1;
+ if (paramLength == argLength) { // accept X[] but not X or X[][]
+ TypeBinding varArgType = parameters[lastIndex]; // is an ArrayBinding by definition
+ TypeBinding lastArgument = arguments[lastIndex];
+ if (varArgType != lastArgument && !lastArgument.isCompatibleWith(varArgType))
+ return false;
+ } else if (paramLength < argLength) { // all remainig argument types must be compatible with the elementsType of varArgType
+ TypeBinding varArgType = ((ArrayBinding) parameters[lastIndex]).elementsType();
+ for (int i = lastIndex; i < argLength; i++)
+ if (varArgType != arguments[i] && !arguments[i].isCompatibleWith(varArgType))
+ return false;
+ } else if (lastIndex != argLength) { // can call foo(int i, X ... x) with foo(1) but NOT foo();
+ return false;
+ }
+ // now compare standard arguments from 0 to lastIndex
+ } else {
+ if(paramLength != argLength)
+ return false;
+ }
+ for (int i = 0; i < lastIndex; i++)
+ if (parameters[i] != arguments[i] && !arguments[i].isCompatibleWith(parameters[i]))
+ return false;
+ return true;
+ }
+
+ private void buildContext(
+ ASTNode astNode,
+ ASTNode astNodeParent,
+ CompilationUnitDeclaration compilationUnitDeclaration,
+ Binding qualifiedBinding,
+ Scope scope) {
+ InternalCompletionContext context = new InternalCompletionContext();
+ if (this.requestor.isExtendedContextRequired()) {
+ context.setExtendedData(
+ this.typeRoot,
+ compilationUnitDeclaration,
+ this.lookupEnvironment,
+ scope,
+ astNode,
+ this.owner,
+ this.parser);
+ }
+
+ // build expected types context
+ if (this.expectedTypesPtr > -1) {
+ int length = this.expectedTypesPtr + 1;
+ char[][] expTypes = new char[length][];
+ char[][] expKeys = new char[length][];
+ for (int i = 0; i < length; i++) {
+ expTypes[i] = getSignature(this.expectedTypes[i]);
+ expKeys[i] = this.expectedTypes[i].computeUniqueKey();
+ }
+ context.setExpectedTypesSignatures(expTypes);
+ context.setExpectedTypesKeys(expKeys);
+ }
+
+ context.setOffset(this.actualCompletionPosition + 1 - this.offset);
+
+ // Set javadoc info
+ if (astNode instanceof CompletionOnJavadoc) {
+ this.assistNodeInJavadoc = ((CompletionOnJavadoc)astNode).getCompletionFlags();
+ context.setJavadoc(this.assistNodeInJavadoc);
+ }
+
+ if (!(astNode instanceof CompletionOnJavadoc)) {
+ CompletionScanner scanner = (CompletionScanner)this.parser.scanner;
+ context.setToken(scanner.completionIdentifier);
+ context.setTokenRange(
+ scanner.completedIdentifierStart - this.offset,
+ scanner.completedIdentifierEnd - this.offset,
+ scanner.endOfEmptyToken - this.offset);
+ } else if(astNode instanceof CompletionOnJavadocTag) {
+ CompletionOnJavadocTag javadocTag = (CompletionOnJavadocTag) astNode;
+ context.setToken(CharOperation.concat(new char[]{'@'}, javadocTag.token));
+ context.setTokenRange(
+ javadocTag.tagSourceStart - this.offset,
+ javadocTag.tagSourceEnd - this.offset,
+ ((CompletionScanner)this.parser.javadocParser.scanner).endOfEmptyToken - this.offset);
+ } else {
+ CompletionScanner scanner = (CompletionScanner)this.parser.javadocParser.scanner;
+ context.setToken(scanner.completionIdentifier);
+ context.setTokenRange(
+ scanner.completedIdentifierStart - this.offset,
+ scanner.completedIdentifierEnd - this.offset,
+ scanner.endOfEmptyToken - this.offset);
+ }
+
+ if(astNode instanceof CompletionOnStringLiteral) {
+ context.setTokenKind(CompletionContext.TOKEN_KIND_STRING_LITERAL);
+ } else {
+ context.setTokenKind(CompletionContext.TOKEN_KIND_NAME);
+ }
+
+ buildTokenLocationContext(context, scope, astNode, astNodeParent);
+
+ if(DEBUG) {
+ System.out.println(context.toString());
+ }
+ this.requestor.acceptContext(context);
+ }
+
+ private void buildTokenLocationContext(InternalCompletionContext context, Scope scope, ASTNode astNode, ASTNode astNodeParent) {
+ if (scope == null || context.isInJavadoc()) return;
+
+ if (astNode instanceof CompletionOnFieldType) {
+ CompletionOnFieldType field = (CompletionOnFieldType) astNode;
+ if (!field.isLocalVariable &&
+ field.modifiers == ClassFileConstants.AccDefault &&
+ (field.annotations == null || field.annotations.length == 0)) {
+ context.setTokenLocation(CompletionContext.TL_MEMBER_START);
+ }
+ } else if (astNode instanceof CompletionOnMethodReturnType) {
+ CompletionOnMethodReturnType method = (CompletionOnMethodReturnType) astNode;
+ if (method.modifiers == ClassFileConstants.AccDefault &&
+ (method.annotations == null || method.annotations.length == 0)) {
+ context.setTokenLocation(CompletionContext.TL_MEMBER_START);
+ }
+ } else {
+ ReferenceContext referenceContext = scope.referenceContext();
+ if (referenceContext instanceof AbstractMethodDeclaration) {
+ AbstractMethodDeclaration methodDeclaration = (AbstractMethodDeclaration)referenceContext;
+ if (methodDeclaration.bodyStart <= astNode.sourceStart &&
+ astNode.sourceEnd <= methodDeclaration.bodyEnd) {
+ // completion is inside a method body
+ if (astNodeParent == null &&
+ astNode instanceof CompletionOnSingleNameReference &&
+ !((CompletionOnSingleNameReference)astNode).isPrecededByModifiers) {
+ context.setTokenLocation(CompletionContext.TL_STATEMENT_START);
+ }
+ }
+ } else if (referenceContext instanceof TypeDeclaration) {
+ TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
+ FieldDeclaration[] fields = typeDeclaration.fields;
+ if (fields != null) {
+ done : for (int i = 0; i < fields.length; i++) {
+ if (fields[i] instanceof Initializer) {
+ Initializer initializer = (Initializer) fields[i];
+ if (initializer.block.sourceStart <= astNode.sourceStart &&
+ astNode.sourceStart < initializer.bodyEnd) {
+ // completion is inside an initializer
+ if (astNodeParent == null &&
+ astNode instanceof CompletionOnSingleNameReference &&
+ !((CompletionOnSingleNameReference)astNode).isPrecededByModifiers) {
+ context.setTokenLocation(CompletionContext.TL_STATEMENT_START);
+ }
+ break done;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ void checkCancel() {
+ if (this.monitor != null && this.monitor.isCanceled()) {
+ throw new OperationCanceledException();
+ }
+ }
+
+ private boolean complete(
+ ASTNode astNode,
+ ASTNode astNodeParent,
+ ASTNode enclosingNode,
+ CompilationUnitDeclaration compilationUnitDeclaration,
+ Binding qualifiedBinding,
+ Scope scope,
+ boolean insideTypeAnnotation) {
+
+ setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd);
+
+ scope = computeForbiddenBindings(astNode, astNodeParent, scope);
+ computeUninterestingBindings(astNodeParent, scope);
+ if(astNodeParent != null) {
+ if(!isValidParent(astNodeParent, astNode, scope)) return false;
+ computeExpectedTypes(astNodeParent, astNode, scope);
+ }
+
+ buildContext(astNode, astNodeParent, compilationUnitDeclaration, qualifiedBinding, scope);
+
+ if (astNode instanceof CompletionOnFieldType) {
+ completionOnFieldType(astNode, scope);
+ } else if (astNode instanceof CompletionOnMethodReturnType) {
+ completionOnMethodReturnType(astNode, scope);
+ } else if (astNode instanceof CompletionOnSingleNameReference) {
+ completionOnSingleNameReference(astNode, astNodeParent, scope, insideTypeAnnotation);
+ } else if (astNode instanceof CompletionOnSingleTypeReference) {
+ completionOnSingleTypeReference(astNode, astNodeParent, qualifiedBinding, scope);
+ } else if (astNode instanceof CompletionOnQualifiedNameReference) {
+ completionOnQualifiedNameReference(astNode, enclosingNode, qualifiedBinding, scope, insideTypeAnnotation);
+ } else if (astNode instanceof CompletionOnQualifiedTypeReference) {
+ completionOnQualifiedTypeReference(astNode, astNodeParent, qualifiedBinding, scope);
+ } else if (astNode instanceof CompletionOnMemberAccess) {
+ completionOnMemberAccess(astNode, enclosingNode, qualifiedBinding, scope, insideTypeAnnotation);
+ } else if (astNode instanceof CompletionOnMessageSend) {
+ completionOnMessageSend(astNode, qualifiedBinding, scope);
+//{ObjectTeams: complete rhs method spec in a callout or callin:
+ } else if (astNode instanceof CompletionOnMethodSpec) {
+ completionOnMethodSpec(astNode, qualifiedBinding, scope);
+ } else if (astNode instanceof CompletionOnFieldAccessSpec) {
+ completionOnFieldAccessSpec(astNode, qualifiedBinding, scope);
+// SH}
+ } else if (astNode instanceof CompletionOnExplicitConstructorCall) {
+ completionOnExplicitConstructorCall(astNode, qualifiedBinding, scope);
+ } else if (astNode instanceof CompletionOnQualifiedAllocationExpression) {
+ completionOnQualifiedAllocationExpression(astNode, qualifiedBinding, scope);
+ } else if (astNode instanceof CompletionOnClassLiteralAccess) {
+ completionOnClassLiteralAccess(astNode, qualifiedBinding, scope);
+ } else if (astNode instanceof CompletionOnMethodName) {
+ completionOnMethodName(astNode, scope);
+ } else if (astNode instanceof CompletionOnFieldName) {
+ completionOnFieldName(astNode, scope);
+ } else if (astNode instanceof CompletionOnLocalName) {
+ completionOnLocalOrArgumentName(astNode, scope);
+ } else if (astNode instanceof CompletionOnArgumentName) {
+ completionOnLocalOrArgumentName(astNode, scope);
+ } else if (astNode instanceof CompletionOnKeyword) {
+ completionOnKeyword(astNode);
+ } else if (astNode instanceof CompletionOnParameterizedQualifiedTypeReference) {
+ completionOnParameterizedQualifiedTypeReference(astNode, astNodeParent, qualifiedBinding, scope);
+ } else if (astNode instanceof CompletionOnMarkerAnnotationName) {
+ completionOnMarkerAnnotationName(astNode, qualifiedBinding, scope);
+ } else if (astNode instanceof CompletionOnMemberValueName) {
+ completionOnMemberValueName(astNode, astNodeParent, scope, insideTypeAnnotation);
+ } else if(astNode instanceof CompletionOnBranchStatementLabel) {
+ completionOnBranchStatementLabel(astNode);
+ } else if(astNode instanceof CompletionOnMessageSendName) {
+ completionOnMessageSendName(astNode, qualifiedBinding, scope);
+ // Completion on Javadoc nodes
+ } else if ((astNode.bits & ASTNode.InsideJavadoc) != 0) {
+ if (astNode instanceof CompletionOnJavadocSingleTypeReference) {
+ completionOnJavadocSingleTypeReference(astNode, scope);
+ } else if (astNode instanceof CompletionOnJavadocQualifiedTypeReference) {
+ completionOnJavadocQualifiedTypeReference(astNode, qualifiedBinding, scope);
+ } else if (astNode instanceof CompletionOnJavadocFieldReference) {
+ completionOnJavadocFieldReference(astNode, scope);
+ } else if (astNode instanceof CompletionOnJavadocMessageSend) {
+ completionOnJavadocMessageSend(astNode, qualifiedBinding, scope);
+ } else if (astNode instanceof CompletionOnJavadocAllocationExpression) {
+ completionOnJavadocAllocationExpression(astNode, qualifiedBinding, scope);
+ } else if (astNode instanceof CompletionOnJavadocParamNameReference) {
+ completionOnJavadocParamNameReference(astNode);
+ } else if (astNode instanceof CompletionOnJavadocTypeParamReference) {
+ completionOnJavadocTypeParamReference(astNode);
+ } else if (astNode instanceof CompletionOnJavadocTag) {
+ completionOnJavadocTag(astNode);
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Ask the engine to compute a completion at the specified position
+ * of the given compilation unit.
+ *
+ * No return
+ * completion results are answered through a requestor.
+ *
+ * @param sourceUnit org.eclipse.jdt.internal.compiler.env.ICompilationUnit
+ * the source of the current compilation unit.
+ *
+ * @param completionPosition int
+ * a position in the source where the completion is taking place.
+ * This position is relative to the source provided.
+ */
+ public void complete(ICompilationUnit sourceUnit, int completionPosition, int pos, ITypeRoot root) {
+
+ if(DEBUG) {
+ System.out.print("COMPLETION IN "); //$NON-NLS-1$
+ System.out.print(sourceUnit.getFileName());
+ System.out.print(" AT POSITION "); //$NON-NLS-1$
+ System.out.println(completionPosition);
+ System.out.println("COMPLETION - Source :"); //$NON-NLS-1$
+ System.out.println(sourceUnit.getContents());
+ }
+ if (this.monitor != null) this.monitor.beginTask(Messages.engine_completing, IProgressMonitor.UNKNOWN);
+ this.requestor.beginReporting();
+ boolean contextAccepted = false;
+ try {
+ this.fileName = sourceUnit.getFileName();
+ this.actualCompletionPosition = completionPosition - 1;
+ this.offset = pos;
+ this.typeRoot = root;
+
+ this.checkCancel();
+
+ // for now until we can change the UI.
+ CompilationResult result = new CompilationResult(sourceUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit);
+ CompilationUnitDeclaration parsedUnit = this.parser.dietParse(sourceUnit, result, this.actualCompletionPosition);
+
+ // boolean completionNodeFound = false;
+ if (parsedUnit != null) {
+ if(DEBUG) {
+ System.out.println("COMPLETION - Diet AST :"); //$NON-NLS-1$
+ System.out.println(parsedUnit.toString());
+ }
+
+ // scan the package & import statements first
+ if (parsedUnit.currentPackage instanceof CompletionOnPackageReference) {
+ contextAccepted = true;
+ buildContext(parsedUnit.currentPackage, null, parsedUnit, null, null);
+ if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
+ findPackages((CompletionOnPackageReference) parsedUnit.currentPackage);
+ }
+ if(this.noProposal && this.problem != null) {
+ this.requestor.completionFailure(this.problem);
+ if(DEBUG) {
+ this.printDebug(this.problem);
+ }
+ }
+ return;
+ }
+
+ ImportReference[] imports = parsedUnit.imports;
+ if (imports != null) {
+ for (int i = 0, length = imports.length; i < length; i++) {
+ ImportReference importReference = imports[i];
+ if (importReference instanceof CompletionOnImportReference) {
+//{ObjectTeams: guard with setup/release, rely on Dependencies instead of manually invoking three steps:
+ try {
+ Dependencies.setup(this, this.parser, this.lookupEnvironment, true, true);
+// km(merge) }
+ this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
+ if ((this.unitScope = parsedUnit.scope) != null) {
+ contextAccepted = true;
+ buildContext(importReference, null, parsedUnit, null, null);
+
+ long positions = importReference.sourcePositions[importReference.tokens.length - 1];
+ setSourceAndTokenRange((int) (positions >>> 32), (int) positions);
+
+ char[][] oldTokens = importReference.tokens;
+ int tokenCount = oldTokens.length;
+ if (tokenCount == 1) {
+ findImports((CompletionOnImportReference)importReference, true);
+ } else if(tokenCount > 1){
+ this.insideQualifiedReference = true;
+
+ char[] lastToken = oldTokens[tokenCount - 1];
+ char[][] qualifierTokens = CharOperation.subarray(oldTokens, 0, tokenCount - 1);
+
+ Binding binding = this.unitScope.getTypeOrPackage(qualifierTokens);
+ if(binding != null) {
+ if(binding instanceof PackageBinding) {
+ findImports((CompletionOnImportReference)importReference, false);
+ } else {
+ ReferenceBinding ref = (ReferenceBinding) binding;
+
+ if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+ findImportsOfMemberTypes(lastToken, ref, importReference.isStatic());
+ }
+ if(importReference.isStatic()) {
+
+ if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
+ findImportsOfStaticFields(lastToken, ref);
+ }
+ if(!this.requestor.isIgnored(CompletionProposal.METHOD_NAME_REFERENCE)) {
+ findImportsOfStaticMethods(lastToken, ref);
+ }
+ }
+ }
+ }
+ }
+
+ if(this.noProposal && this.problem != null) {
+ this.requestor.completionFailure(this.problem);
+ if(DEBUG) {
+ this.printDebug(this.problem);
+ }
+ }
+ }
+//{ObjectTeams:
+ } finally {
+ Dependencies.release(this);
+ }
+// km(merge) }
+ return;
+ } else if(importReference instanceof CompletionOnKeyword) {
+ contextAccepted = true;
+ buildContext(importReference, null, parsedUnit, null, null);
+ if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+ setSourceAndTokenRange(importReference.sourceStart, importReference.sourceEnd);
+ CompletionOnKeyword keyword = (CompletionOnKeyword)importReference;
+ findKeywords(keyword.getToken(), keyword.getPossibleKeywords(), false, false);
+ }
+ if(this.noProposal && this.problem != null) {
+ this.requestor.completionFailure(this.problem);
+ if(DEBUG) {
+ this.printDebug(this.problem);
+ }
+ }
+ return;
+ }
+ }
+ }
+
+ if (parsedUnit.types != null) {
+//{ObjectTeams: guard this block by setup/release:
+ Dependencies.setup(this, this.parser, this.lookupEnvironment, true, true);
+ // statements are explicitly requested for the completion position, other statements are not needed
+// orig:
+
+ try {
+ this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
+
+ if ((this.unitScope = parsedUnit.scope) != null) {
+ this.source = sourceUnit.getContents();
+ this.lookupEnvironment.completeTypeBindings(parsedUnit, true);
+/*
+ parsedUnit.scope.faultInTypes();
+ :giro */
+ Dependencies.ensureState(parsedUnit, ITranslationStates.STATE_METHODS_PARSED-1);
+
+// orig:
+ parseBlockStatements(parsedUnit, this.actualCompletionPosition);
+// :giro
+ StateHelper.setStateRecursive(parsedUnit, ITranslationStates.STATE_METHODS_PARSED, true);
+// orig:
+ if(DEBUG) {
+ System.out.println("COMPLETION - AST :"); //$NON-NLS-1$
+ System.out.println(parsedUnit.toString());
+ }
+// :giro
+/* orig:
+ parsedUnit.resolve();
+ :giro */
+ Dependencies.ensureState(parsedUnit, ITranslationStates.STATE_LATE_ELEMENTS_COPIED);
+ // generateStatements also resolves some, notably parameter mappings as inserted into mapping wrappers.
+// SH}
+ }
+ } catch (CompletionNodeFound e) {
+//{ObjectTeams: Dependencies might drive to CompletionNodeFound already during buildTypeBindings:
+ if (this.unitScope == null)
+ this.unitScope = parsedUnit.scope;
+// SH}
+ // completionNodeFound = true;
+ if (e.astNode != null) {
+ // if null then we found a problem in the completion node
+ if(DEBUG) {
+ System.out.print("COMPLETION - Completion node : "); //$NON-NLS-1$
+ System.out.println(e.astNode.toString());
+ if(this.parser.assistNodeParent != null) {
+ System.out.print("COMPLETION - Parent Node : "); //$NON-NLS-1$
+ System.out.println(this.parser.assistNodeParent);
+ }
+ }
+ this.lookupEnvironment.unitBeingCompleted = parsedUnit; // better resilient to further error reporting
+ contextAccepted =
+ complete(
+ e.astNode,
+ this.parser.assistNodeParent,
+ this.parser.enclosingNode,
+ parsedUnit,
+ e.qualifiedBinding,
+ e.scope,
+ e.insideTypeAnnotation);
+ }
+ }
+//{ObjectTeams:
+ finally {
+ Dependencies.release(this);
+ }
+//SH}
+ }
+ }
+
+ if(this.noProposal && this.problem != null) {
+ if(!contextAccepted) {
+ contextAccepted = true;
+ InternalCompletionContext context = new InternalCompletionContext();
+ context.setOffset(completionPosition - this.offset);
+ context.setTokenKind(CompletionContext.TOKEN_KIND_UNKNOWN);
+ if (this.requestor.isExtendedContextRequired()) context.setExtended();
+ this.requestor.acceptContext(context);
+ }
+ this.requestor.completionFailure(this.problem);
+ if(DEBUG) {
+ this.printDebug(this.problem);
+ }
+ }
+ /* Ignore package, import, class & interface keywords for now...
+ if (!completionNodeFound) {
+ if (parsedUnit == null || parsedUnit.types == null) {
+ // this is not good enough... can still be trying to define a second type
+ CompletionScanner scanner = (CompletionScanner) this.parser.scanner;
+ setSourceRange(scanner.completedIdentifierStart, scanner.completedIdentifierEnd);
+ findKeywords(scanner.completionIdentifier, mainDeclarations, null);
+ }
+ // currently have no way to know if extends/implements are possible keywords
+ }
+ */
+ } catch (IndexOutOfBoundsException e) { // work-around internal failure - 1GEMF6D
+ if(DEBUG) {
+ System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
+ e.printStackTrace(System.out);
+ }
+ } catch (InvalidCursorLocation e) { // may eventually report a usefull error
+ if(DEBUG) {
+ System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
+ e.printStackTrace(System.out);
+ }
+ } catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object
+ if(DEBUG) {
+ System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
+ e.printStackTrace(System.out);
+ }
+ } catch (CompletionNodeFound e){ // internal failure - bugs 5618
+ if(DEBUG) {
+ System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
+ e.printStackTrace(System.out);
+ }
+ } finally {
+ if(!contextAccepted) {
+ contextAccepted = true;
+ InternalCompletionContext context = new InternalCompletionContext();
+ context.setTokenKind(CompletionContext.TOKEN_KIND_UNKNOWN);
+ context.setOffset(completionPosition - this.offset);
+ if (this.requestor.isExtendedContextRequired()) context.setExtended();
+ this.requestor.acceptContext(context);
+ }
+ this.requestor.endReporting();
+ if (this.monitor != null) this.monitor.done();
+ reset();
+ }
+ }
+
+ public void complete(IType type, char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic){
+ if(this.requestor != null){
+ this.requestor.beginReporting();
+ }
+ boolean contextAccepted = false;
+ IType topLevelType = type;
+ while(topLevelType.getDeclaringType() != null) {
+ topLevelType = topLevelType.getDeclaringType();
+ }
+
+ this.fileName = topLevelType.getParent().getElementName().toCharArray();
+ CompilationResult compilationResult = new CompilationResult(this.fileName, 1, 1, this.compilerOptions.maxProblemsPerUnit);
+
+ CompilationUnitDeclaration compilationUnit = null;
+
+ try {
+ // TypeConverter is used instead of SourceTypeConverter because the type
+ // to convert can be a binary type or a source type
+ TypeDeclaration typeDeclaration = null;
+ if (type instanceof SourceType) {
+ SourceType sourceType = (SourceType) type;
+ ISourceType info = (ISourceType) sourceType.getElementInfo();
+ compilationUnit = SourceTypeConverter.buildCompilationUnit(
+ new ISourceType[] {info},//sourceTypes[0] is always toplevel here
+ SourceTypeConverter.FIELD_AND_METHOD // need field and methods
+ | SourceTypeConverter.MEMBER_TYPE, // need member types
+ // no need for field initialization
+ this.problemReporter,
+ compilationResult);
+ if (compilationUnit.types != null)
+ typeDeclaration = compilationUnit.types[0];
+ } else {
+ compilationUnit = new CompilationUnitDeclaration(this.problemReporter, compilationResult, 0);
+ typeDeclaration = new BinaryTypeConverter(this.parser.problemReporter(), compilationResult, null/*no need to remember type names*/).buildTypeDeclaration(type, compilationUnit);
+ }
+
+ if(typeDeclaration != null) {
+ // build AST from snippet
+ Initializer fakeInitializer = parseSnippeInitializer(snippet, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic);
+
+ // merge AST
+ FieldDeclaration[] oldFields = typeDeclaration.fields;
+ FieldDeclaration[] newFields = null;
+ if (oldFields != null) {
+ newFields = new FieldDeclaration[oldFields.length + 1];
+ System.arraycopy(oldFields, 0, newFields, 0, oldFields.length);
+ newFields[oldFields.length] = fakeInitializer;
+ } else {
+ newFields = new FieldDeclaration[] {fakeInitializer};
+ }
+ typeDeclaration.fields = newFields;
+
+ if(DEBUG) {
+ System.out.println("SNIPPET COMPLETION AST :"); //$NON-NLS-1$
+ System.out.println(compilationUnit.toString());
+ }
+
+ if (compilationUnit.types != null) {
+ try {
+ //{ObjectTeams: guard with setup/release, rely on Dependencies instead of manually invoking three steps:
+ Dependencies.setup(this, this.parser, this.lookupEnvironment, true, true);
+ //orig:
+ this.lookupEnvironment.buildTypeBindings(compilationUnit, null /*no access restriction*/);
+
+ if ((this.unitScope = compilationUnit.scope) != null) {
+ this.lookupEnvironment.completeTypeBindings(compilationUnit, true);
+ //:giro
+ /* orig:
+ compilationUnit.scope.faultInTypes();
+ compilationUnit.resolve();
+ :giro */
+ Dependencies.ensureState(compilationUnit, ITranslationStates.STATE_LATE_ELEMENTS_COPIED);
+ // generateStatements also resolves some, notably parameter mappings as inserted into mapping wrappers.
+ // SH}
+ }
+ } catch (CompletionNodeFound e) {
+ // completionNodeFound = true;
+ if (e.astNode != null) {
+ // if null then we found a problem in the completion node
+ contextAccepted =
+ complete(
+ e.astNode,
+ this.parser.assistNodeParent,
+ this.parser.enclosingNode,
+ compilationUnit,
+ e.qualifiedBinding,
+ e.scope,
+ e.insideTypeAnnotation);
+ }
+ }
+ //{ObjectTeams: moved here
+ finally {
+ Dependencies.release(this);
+ }
+ //km}
+ }
+ if(this.noProposal && this.problem != null) {
+ if(!contextAccepted) {
+ contextAccepted = true;
+ InternalCompletionContext context = new InternalCompletionContext();
+ if (this.requestor.isExtendedContextRequired()) context.setExtended();
+ this.requestor.acceptContext(context);
+ }
+ this.requestor.completionFailure(this.problem);
+ if(DEBUG) {
+ this.printDebug(this.problem);
+ }
+ }
+ }
+ } catch (IndexOutOfBoundsException e) { // work-around internal failure - 1GEMF6D (added with fix of 99629)
+ if(DEBUG) {
+ System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
+ e.printStackTrace(System.out);
+ }
+ } catch (InvalidCursorLocation e) { // may eventually report a usefull error (added to fix 99629)
+ if(DEBUG) {
+ System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
+ e.printStackTrace(System.out);
+ }
+ } catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object (added with fix of 99629)
+ if(DEBUG) {
+ System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
+ e.printStackTrace(System.out);
+ }
+ } catch (CompletionNodeFound e){ // internal failure - bugs 5618 (added with fix of 99629)
+ if(DEBUG) {
+ System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
+ e.printStackTrace(System.out);
+ }
+ } catch(JavaModelException e) {
+ // Do nothing
+ }
+ if(!contextAccepted) {
+ contextAccepted = true;
+ InternalCompletionContext context = new InternalCompletionContext();
+ if (this.requestor.isExtendedContextRequired()) context.setExtended();
+ this.requestor.acceptContext(context);
+ }
+ if(this.requestor != null){
+ this.requestor.endReporting();
+ }
+ }
+
+ private void completionOnBranchStatementLabel(ASTNode astNode) {
+ if (!this.requestor.isIgnored(CompletionProposal.LABEL_REF)) {
+ CompletionOnBranchStatementLabel label = (CompletionOnBranchStatementLabel) astNode;
+ this.completionToken = label.label;
+ findLabels(this.completionToken, label.possibleLabels);
+ }
+ }
+
+ private void completionOnClassLiteralAccess(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
+ if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
+ CompletionOnClassLiteralAccess access = (CompletionOnClassLiteralAccess) astNode;
+ setSourceAndTokenRange(access.classStart, access.sourceEnd);
+ this.completionToken = access.completionIdentifier;
+ findClassField(
+ this.completionToken,
+ (TypeBinding) qualifiedBinding,
+ scope,
+ null,
+ null,
+ null,
+ false);
+ }
+ }
+
+ private void completionOnExplicitConstructorCall(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
+ if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
+ setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false);
+ CompletionOnExplicitConstructorCall constructorCall = (CompletionOnExplicitConstructorCall) astNode;
+ TypeBinding[] argTypes = computeTypes(constructorCall.arguments);
+ findConstructors(
+ (ReferenceBinding) qualifiedBinding,
+ argTypes,
+ scope,
+ constructorCall,
+ false,
+ null,
+ null,
+ null,
+ false);
+ }
+ }
+
+ private void completionOnFieldName(ASTNode astNode, Scope scope) {
+ if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
+ CompletionOnFieldName field = (CompletionOnFieldName) astNode;
+
+ FieldBinding[] fields = scope.enclosingSourceType().fields();
+ char[][] excludeNames = new char[fields.length][];
+ for(int i = 0 ; i < fields.length ; i++){
+ excludeNames[i] = fields[i].name;
+ }
+
+ this.completionToken = field.realName;
+
+
+ int kind =
+ (field.modifiers & ClassFileConstants.AccStatic) == 0 ?
+ InternalNamingConventions.VK_INSTANCE_FIELD :
+ (field.modifiers & ClassFileConstants.AccFinal) == 0 ?
+ InternalNamingConventions.VK_STATIC_FIELD :
+ InternalNamingConventions.VK_STATIC_FINAL_FIELD;
+
+ findVariableNames(field.realName, field.type, excludeNames, null, kind);
+ }
+ }
+
+ private void completionOnFieldType(ASTNode astNode, Scope scope) {
+ CompletionOnFieldType field = (CompletionOnFieldType) astNode;
+ CompletionOnSingleTypeReference type = (CompletionOnSingleTypeReference) field.type;
+ this.completionToken = type.token;
+ setSourceAndTokenRange(type.sourceStart, type.sourceEnd);
+
+ findTypesAndPackages(this.completionToken, scope, true, true, new ObjectVector());
+ if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+ findKeywordsForMember(this.completionToken, field.modifiers);
+ }
+
+ if (!field.isLocalVariable && field.modifiers == ClassFileConstants.AccDefault) {
+ SourceTypeBinding enclosingType = scope.enclosingSourceType();
+ if (!enclosingType.isAnnotationType()) {
+ if (!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
+ findMethodDeclarations(
+ this.completionToken,
+ enclosingType,
+ scope,
+ new ObjectVector(),
+ null,
+ null,
+ null,
+ false);
+ }
+ if (!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
+ proposeNewMethod(this.completionToken, enclosingType);
+ }
+ }
+ }
+ }
+ //TODO
+ private void completionOnJavadocAllocationExpression(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
+ // setSourceRange(astNode.sourceStart, astNode.sourceEnd, false);
+
+ CompletionOnJavadocAllocationExpression allocExpression = (CompletionOnJavadocAllocationExpression) astNode;
+ this.javadocTagPosition = allocExpression.tagSourceStart;
+ int rangeStart = astNode.sourceStart;
+ if (allocExpression.type.isThis()) {
+ if (allocExpression.completeInText()) {
+ rangeStart = allocExpression.separatorPosition;
+ }
+ } else if (allocExpression.completeInText()) {
+ rangeStart = allocExpression.type.sourceStart;
+ }
+ setSourceAndTokenRange(rangeStart, astNode.sourceEnd, false);
+ TypeBinding[] argTypes = computeTypes(allocExpression.arguments);
+
+ ReferenceBinding ref = (ReferenceBinding) qualifiedBinding;
+ if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF) && ref.isClass()) {
+ findConstructors(ref, argTypes, scope, allocExpression, false, null, null, null, false);
+ }
+ }
+ //TODO
+ private void completionOnJavadocFieldReference(ASTNode astNode, Scope scope) {
+ this.insideQualifiedReference = true;
+ CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) astNode;
+ this.completionToken = fieldRef.token;
+ long completionPosition = fieldRef.nameSourcePosition;
+ this.javadocTagPosition = fieldRef.tagSourceStart;
+
+ if (fieldRef.actualReceiverType != null && fieldRef.actualReceiverType.isValidBinding()) {
+ ReferenceBinding receiverType = (ReferenceBinding) fieldRef.actualReceiverType;
+ int rangeStart = (int) (completionPosition >>> 32);
+ if (fieldRef.receiver.isThis()) {
+ if (fieldRef.completeInText()) {
+ rangeStart = fieldRef.separatorPosition;
+ }
+ } else if (fieldRef.completeInText()) {
+ rangeStart = fieldRef.receiver.sourceStart;
+ }
+ setSourceAndTokenRange(rangeStart, (int) completionPosition);
+
+ if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)
+ || !this.requestor.isIgnored(CompletionProposal.JAVADOC_FIELD_REF)) {
+ findFields(this.completionToken,
+ receiverType,
+ scope,
+ new ObjectVector(),
+ new ObjectVector(),
+ false, /*not only static */
+ fieldRef,
+ scope,
+ false,
+ true,
+ null,
+ null,
+ null,
+ false,
+ null,
+ -1,
+ -1);
+ }
+
+ if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)
+ || !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
+ findMethods(
+ this.completionToken,
+ null,
+ null,
+ receiverType,
+ scope,
+ new ObjectVector(),
+ false, /*not only static */
+ false,
+ fieldRef,
+ scope,
+ false,
+ false,
+ true,
+ null,
+ null,
+ null,
+ false,
+ null,
+ -1,
+ -1);
+ if (fieldRef.actualReceiverType instanceof ReferenceBinding) {
+ ReferenceBinding refBinding = (ReferenceBinding)fieldRef.actualReceiverType;
+ if (this.completionToken == null
+ || CharOperation.prefixEquals(this.completionToken, refBinding.sourceName)
+ || (this.options.camelCaseMatch && CharOperation.camelCaseMatch(this.completionToken, refBinding.sourceName))) {
+ findConstructors(refBinding, null, scope, fieldRef, false, null, null, null, false);
+ }
+ }
+ }
+ }
+ }
+ //TODO
+ private void completionOnJavadocMessageSend(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
+ CompletionOnJavadocMessageSend messageSend = (CompletionOnJavadocMessageSend) astNode;
+ TypeBinding[] argTypes = null; //computeTypes(messageSend.arguments);
+ this.completionToken = messageSend.selector;
+ this.javadocTagPosition = messageSend.tagSourceStart;
+
+ // Set source range
+ int rangeStart = astNode.sourceStart;
+ if (messageSend.receiver.isThis()) {
+ if (messageSend.completeInText()) {
+ rangeStart = messageSend.separatorPosition;
+ }
+ } else if (messageSend.completeInText()) {
+ rangeStart = messageSend.receiver.sourceStart;
+ }
+ setSourceAndTokenRange(rangeStart, astNode.sourceEnd, false);
+
+ if (qualifiedBinding == null) {
+ if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
+ findImplicitMessageSends(this.completionToken, argTypes, scope, messageSend, scope, new ObjectVector());
+ }
+ } else if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
+ findMethods(
+ this.completionToken,
+ null,
+ argTypes,
+ (ReferenceBinding) ((ReferenceBinding) qualifiedBinding).capture(scope, messageSend.receiver.sourceEnd),
+ scope,
+ new ObjectVector(),
+ false,
+ false/* prefix match */,
+ messageSend,
+ scope,
+ false,
+ messageSend.receiver instanceof SuperReference,
+ true,
+ null,
+ null,
+ null,
+ false,
+ null,
+ -1,
+ -1);
+ }
+ }
+ //TODO
+ private void completionOnJavadocParamNameReference(ASTNode astNode) {
+ if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) {
+ CompletionOnJavadocParamNameReference paramRef = (CompletionOnJavadocParamNameReference) astNode;
+ setSourceAndTokenRange(paramRef.tagSourceStart, paramRef.tagSourceEnd);
+ findJavadocParamNames(paramRef.token, paramRef.missingParams, false);
+ findJavadocParamNames(paramRef.token, paramRef.missingTypeParams, true);
+ }
+ }
+ //TODO
+ private void completionOnJavadocQualifiedTypeReference(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
+ this.insideQualifiedReference = true;
+
+ CompletionOnJavadocQualifiedTypeReference typeRef = (CompletionOnJavadocQualifiedTypeReference) astNode;
+ this.completionToken = typeRef.completionIdentifier;
+ long completionPosition = typeRef.sourcePositions[typeRef.tokens.length];
+ this.javadocTagPosition = typeRef.tagSourceStart;
+
+ // get the source positions of the completion identifier
+ if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
+ if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
+ ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF))) {
+ int rangeStart = typeRef.completeInText() ? typeRef.sourceStart : (int) (completionPosition >>> 32);
+ setSourceAndTokenRange(rangeStart, (int) completionPosition);
+ findMemberTypes(
+ this.completionToken,
+ (ReferenceBinding) qualifiedBinding,
+ scope,
+ scope.enclosingSourceType(),
+ false,
+ false,
+ new ObjectVector(),
+ null,
+ null,
+ null,
+ false);
+ }
+ } else if (qualifiedBinding instanceof PackageBinding) {
+
+ setSourceRange(astNode.sourceStart, (int) completionPosition);
+ int rangeStart = typeRef.completeInText() ? typeRef.sourceStart : (int) (completionPosition >>> 32);
+ setTokenRange(rangeStart, (int) completionPosition);
+ // replace to the end of the completion identifier
+ findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
+ }
+ }
+ //TODO
+ private void completionOnJavadocSingleTypeReference(ASTNode astNode, Scope scope) {
+ CompletionOnJavadocSingleTypeReference typeRef = (CompletionOnJavadocSingleTypeReference) astNode;
+ this.completionToken = typeRef.token;
+ this.javadocTagPosition = typeRef.tagSourceStart;
+ setSourceAndTokenRange(typeRef.sourceStart, typeRef.sourceEnd);
+ findTypesAndPackages(
+ this.completionToken,
+ scope,
+ (this.assistNodeInJavadoc & CompletionOnJavadoc.BASE_TYPES) != 0,
+ false,
+ new ObjectVector());
+ }
+ //TODO
+ private void completionOnJavadocTag(ASTNode astNode) {
+ CompletionOnJavadocTag javadocTag = (CompletionOnJavadocTag) astNode;
+ setSourceAndTokenRange(javadocTag.tagSourceStart, javadocTag.sourceEnd);
+ findJavadocBlockTags(javadocTag);
+ findJavadocInlineTags(javadocTag);
+ }
+ //TODO
+ private void completionOnJavadocTypeParamReference(ASTNode astNode) {
+ if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) {
+ CompletionOnJavadocTypeParamReference paramRef = (CompletionOnJavadocTypeParamReference) astNode;
+ setSourceAndTokenRange(paramRef.tagSourceStart, paramRef.tagSourceEnd);
+ findJavadocParamNames(paramRef.token, paramRef.missingParams, true);
+ }
+ }
+
+ private void completionOnKeyword(ASTNode astNode) {
+ if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+ CompletionOnKeyword keyword = (CompletionOnKeyword)astNode;
+ findKeywords(keyword.getToken(), keyword.getPossibleKeywords(), keyword.canCompleteEmptyToken(), false);
+ }
+ }
+
+ private void completionOnLocalOrArgumentName(ASTNode astNode, Scope scope) {
+ if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
+ LocalDeclaration variable = (LocalDeclaration) astNode;
+
+ int kind;
+ if (variable instanceof CompletionOnLocalName){
+ this.completionToken = ((CompletionOnLocalName) variable).realName;
+ kind = InternalNamingConventions.VK_LOCAL;
+ } else {
+ CompletionOnArgumentName arg = (CompletionOnArgumentName) variable;
+ this.completionToken = arg.realName;
+ kind = arg.isCatchArgument ? InternalNamingConventions.VK_LOCAL : InternalNamingConventions.VK_PARAMETER;
+ }
+
+ char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, variable);
+
+ char[][] forbiddenNames = findVariableFromUnresolvedReference(variable, (BlockScope)scope, alreadyDefinedName);
+
+ LocalVariableBinding[] locals = ((BlockScope)scope).locals;
+ char[][] discouragedNames = new char[locals.length][];
+ int localCount = 0;
+ for(int i = 0 ; i < locals.length ; i++){
+ if (locals[i] != null) {
+ discouragedNames[localCount++] = locals[i].name;
+ }
+ }
+
+ System.arraycopy(discouragedNames, 0, discouragedNames = new char[localCount][], 0, localCount);
+
+ findVariableNames(this.completionToken, variable.type, discouragedNames, forbiddenNames, kind);
+ }
+ }
+
+ private void completionOnMarkerAnnotationName(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
+ CompletionOnMarkerAnnotationName annot = (CompletionOnMarkerAnnotationName) astNode;
+
+ CompletionOnAnnotationOfType fakeType = (CompletionOnAnnotationOfType)scope.parent.referenceContext();
+ if (fakeType.annotations[0] == annot) {
+ // When the completion is inside a method body the annotation cannot be accuratly attached to the correct node by completion recovery.
+ // So 'targetedElement' is not computed in this case.
+ if (scope.parent.parent == null || !(scope.parent.parent instanceof MethodScope)) {
+ this.targetedElement = computeTargetedElement(fakeType);
+ }
+
+ }
+
+ this.assistNodeIsAnnotation = true;
+ if (annot.type instanceof CompletionOnSingleTypeReference) {
+ CompletionOnSingleTypeReference type = (CompletionOnSingleTypeReference) annot.type;
+ this.completionToken = type.token;
+ setSourceAndTokenRange(type.sourceStart, type.sourceEnd);
+
+ if (scope.parent.parent != null &&
+ !(scope.parent.parent instanceof MethodScope) &&
+ !fakeType.isParameter) {
+
+ if (this.completionToken.length <= Keywords.INTERFACE.length
+ && CharOperation.prefixEquals(this.completionToken, Keywords.INTERFACE, false /* ignore case */
+ )){
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForCaseMatching(this.completionToken, Keywords.INTERFACE);
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords
+ relevance += R_ANNOTATION; // this proposal is most relevant than annotation proposals
+
+ this.noProposal = false;
+ if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+ CompletionProposal proposal = createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
+ proposal.setName(Keywords.INTERFACE);
+ proposal.setCompletion(Keywords.INTERFACE);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ }
+ }
+
+ findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
+ } else if (annot.type instanceof CompletionOnQualifiedTypeReference) {
+ this.insideQualifiedReference = true;
+
+ CompletionOnQualifiedTypeReference type = (CompletionOnQualifiedTypeReference) annot.type;
+ this.completionToken = type.completionIdentifier;
+ long completionPosition = type.sourcePositions[type.tokens.length];
+ if (qualifiedBinding instanceof PackageBinding) {
+
+ setSourceRange(astNode.sourceStart, (int) completionPosition);
+ setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+ // replace to the end of the completion identifier
+ findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
+ } else {
+ setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+
+ findMemberTypes(
+ this.completionToken,
+ (ReferenceBinding) qualifiedBinding,
+ scope,
+ scope.enclosingSourceType(),
+ false,
+ false,
+ new ObjectVector(),
+ null,
+ null,
+ null,
+ false);
+ }
+ }
+ }
+
+ private void completionOnMemberAccess(ASTNode astNode, ASTNode enclosingNode, Binding qualifiedBinding,
+ Scope scope, boolean insideTypeAnnotation) {
+ this.insideQualifiedReference = true;
+ CompletionOnMemberAccess access = (CompletionOnMemberAccess) astNode;
+ long completionPosition = access.nameSourcePosition;
+ setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+
+ this.completionToken = access.token;
+
+ if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
+ // complete method members with missing return type
+ // class X {
+ // Missing f() {return null;}
+ // void foo() {
+ // f().|
+ // }
+ // }
+ if (this.assistNodeInJavadoc == 0 &&
+ (this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
+ this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF))) {
+ ProblemMethodBinding problemMethodBinding = (ProblemMethodBinding) qualifiedBinding;
+ findFieldsAndMethodsFromMissingReturnType(
+ problemMethodBinding.selector,
+ problemMethodBinding.parameters,
+ scope,
+ access,
+ insideTypeAnnotation);
+ }
+ } else {
+ if (!access.isInsideAnnotation) {
+ if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+ findKeywords(this.completionToken, new char[][]{Keywords.NEW}, false, false);
+ }
+
+ ObjectVector fieldsFound = new ObjectVector();
+ ObjectVector methodsFound = new ObjectVector();
+
+ boolean superCall = access.receiver instanceof SuperReference;
+
+ findFieldsAndMethods(
+ this.completionToken,
+ ((TypeBinding) qualifiedBinding).capture(scope, access.receiver.sourceEnd),
+ scope,
+ fieldsFound,
+ methodsFound,
+ access,
+ scope,
+ false,
+ superCall,
+ null,
+ null,
+ null,
+ false,
+ null,
+ -1,
+ -1);
+
+ if (!superCall) {
+
+ checkCancel();
+
+ findFieldsAndMethodsFromCastedReceiver(
+ enclosingNode,
+ qualifiedBinding,
+ scope,
+ fieldsFound,
+ methodsFound,
+ access,
+ scope,
+ access.receiver);
+ }
+ }
+ }
+ }
+
+ private void completionOnMemberValueName(ASTNode astNode, ASTNode astNodeParent, Scope scope,
+ boolean insideTypeAnnotation) {
+ CompletionOnMemberValueName memberValuePair = (CompletionOnMemberValueName) astNode;
+ Annotation annotation = (Annotation) astNodeParent;
+
+ this.completionToken = memberValuePair.name;
+
+ ReferenceBinding annotationType = (ReferenceBinding)annotation.resolvedType;
+
+ if (annotationType != null && annotationType.isAnnotationType()) {
+ if (!this.requestor.isIgnored(CompletionProposal.ANNOTATION_ATTRIBUTE_REF)) {
+ findAnnotationAttributes(this.completionToken, annotation.memberValuePairs(), annotationType);
+ }
+ if (this.assistNodeCanBeSingleMemberAnnotation) {
+ if (this.expectedTypesPtr > -1 && this.expectedTypes[0].isAnnotationType()) {
+ findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
+ } else {
+ if (this.expectedTypesPtr > -1) {
+ this.assistNodeIsEnum = true;
+ done : for (int i = 0; i <= this.expectedTypesPtr; i++) {
+ if (!this.expectedTypes[i].isEnum()) {
+ this.assistNodeIsEnum = false;
+ break done;
+ }
+ }
+
+ }
+ if (scope instanceof BlockScope && !this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
+ char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, FakeInvocationSite);
+
+ findUnresolvedReference(
+ memberValuePair.sourceStart,
+ memberValuePair.sourceEnd,
+ (BlockScope)scope,
+ alreadyDefinedName);
+ }
+ findVariablesAndMethods(
+ this.completionToken,
+ scope,
+ FakeInvocationSite,
+ scope,
+ insideTypeAnnotation,
+ true);
+ // can be the start of a qualified type name
+ findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
+ }
+ }
+ }
+ }
+
+ private void completionOnMessageSend(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
+ setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false);
+
+ CompletionOnMessageSend messageSend = (CompletionOnMessageSend) astNode;
+ TypeBinding[] argTypes = computeTypes(messageSend.arguments);
+ this.completionToken = messageSend.selector;
+ if (qualifiedBinding == null) {
+ if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
+ ObjectVector methodsFound = new ObjectVector();
+
+ findImplicitMessageSends(this.completionToken, argTypes, scope, messageSend, scope, methodsFound);
+
+ checkCancel();
+
+ findLocalMethodsFromStaticImports(
+ this.completionToken,
+ scope,
+ messageSend,
+ scope,
+ true,
+ methodsFound,
+ true);
+ }
+ } else if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
+ findMethods(
+ this.completionToken,
+ null,
+ argTypes,
+ (ReferenceBinding)((ReferenceBinding) qualifiedBinding).capture(scope, messageSend.receiver.sourceEnd),
+ scope,
+ new ObjectVector(),
+ false,
+ true,
+ messageSend,
+ scope,
+ false,
+ messageSend.receiver instanceof SuperReference,
+ false,
+ null,
+ null,
+ null,
+ false,
+ null,
+ -1,
+ -1);
+ }
+ }
+
+ private void completionOnMessageSendName(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
+ if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
+ CompletionOnMessageSendName messageSend = (CompletionOnMessageSendName) astNode;
+
+ this.insideQualifiedReference = true;
+ this.completionToken = messageSend.selector;
+ boolean onlyStatic = false;
+ if (messageSend.receiver instanceof NameReference) {
+ onlyStatic = ((NameReference)messageSend.receiver).isTypeReference();
+ } else if (!(messageSend.receiver instanceof MessageSend) &&
+ !(messageSend.receiver instanceof FieldReference) &&
+ !(messageSend.receiver.isThis())) {
+ onlyStatic = true;
+ }
+
+ TypeBinding receiverType = (TypeBinding)qualifiedBinding;
+
+ if(receiverType != null && receiverType instanceof ReferenceBinding) {
+ TypeBinding[] typeArgTypes = computeTypesIfCorrect(messageSend.typeArguments);
+ if(typeArgTypes != null) {
+ findMethods(
+ this.completionToken,
+ typeArgTypes,
+ null,
+ (ReferenceBinding)receiverType.capture(scope, messageSend.receiver.sourceEnd),
+ scope,
+ new ObjectVector(),
+ onlyStatic,
+ false,
+ messageSend,
+ scope,
+ false,
+ false,
+ false,
+ null,
+ null,
+ null,
+ false,
+ null,
+ -1,
+ -1);
+ }
+ }
+ }
+ }
+
+ private void completionOnMethodName(ASTNode astNode, Scope scope) {
+ if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
+ CompletionOnMethodName method = (CompletionOnMethodName) astNode;
+
+ setSourceAndTokenRange(method.sourceStart, method.selectorEnd);
+
+ FieldBinding[] fields = scope.enclosingSourceType().fields();
+ char[][] excludeNames = new char[fields.length][];
+ for(int i = 0 ; i < fields.length ; i++){
+ excludeNames[i] = fields[i].name;
+ }
+
+ this.completionToken = method.selector;
+
+
+ int kind =
+ (method.modifiers & ClassFileConstants.AccStatic) == 0 ?
+ InternalNamingConventions.VK_INSTANCE_FIELD :
+ (method.modifiers & ClassFileConstants.AccFinal) == 0 ?
+ InternalNamingConventions.VK_STATIC_FIELD :
+ InternalNamingConventions.VK_STATIC_FINAL_FIELD;
+
+ findVariableNames(this.completionToken, method.returnType, excludeNames, null, kind);
+ }
+ }
+
+ private void completionOnMethodReturnType(ASTNode astNode, Scope scope) {
+ CompletionOnMethodReturnType method = (CompletionOnMethodReturnType) astNode;
+ SingleTypeReference type = (CompletionOnSingleTypeReference) method.returnType;
+ this.completionToken = type.token;
+ setSourceAndTokenRange(type.sourceStart, type.sourceEnd);
+ findTypesAndPackages(this.completionToken, scope.parent, true, true, new ObjectVector());
+ if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+ findKeywordsForMember(this.completionToken, method.modifiers);
+ }
+
+ if (method.modifiers == ClassFileConstants.AccDefault) {
+ SourceTypeBinding enclosingType = scope.enclosingSourceType();
+ if (!enclosingType.isAnnotationType()) {
+ if (!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
+ findMethodDeclarations(
+ this.completionToken,
+ scope.enclosingSourceType(),
+ scope,
+ new ObjectVector(),
+ null,
+ null,
+ null,
+ false);
+ }
+ if (!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
+ proposeNewMethod(this.completionToken, scope.enclosingSourceType());
+ }
+ }
+ }
+ }
+
+ private void completionOnParameterizedQualifiedTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope) {
+ if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+ CompletionOnParameterizedQualifiedTypeReference ref = (CompletionOnParameterizedQualifiedTypeReference) astNode;
+
+ this.insideQualifiedReference = true;
+
+ this.assistNodeIsClass = ref.isClass();
+ this.assistNodeIsException = ref.isException();
+ this.assistNodeIsInterface = ref.isInterface();
+ this.assistNodeIsSuperType = ref.isSuperType();
+ this.assistNodeIsExtendedType = assistNodeIsExtendedType(astNode, astNodeParent);
+
+ this.completionToken = ref.completionIdentifier;
+ long completionPosition = ref.sourcePositions[ref.tokens.length];
+ setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+
+ if (qualifiedBinding.problemId() == ProblemReasons.NotFound ||
+ (((ReferenceBinding)qualifiedBinding).tagBits & TagBits.HasMissingType) != 0) {
+ if (this.assistNodeInJavadoc == 0 &&
+ (this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) {
+ if(ref.tokens.length == 1) {
+ findMemberTypesFromMissingType(
+ ref,
+ ref.sourcePositions[0],
+ scope);
+ }
+ }
+ } else {
+ ObjectVector typesFound = new ObjectVector();
+ if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
+ findExceptionFromTryStatement(
+ this.completionToken,
+ (ReferenceBinding)qualifiedBinding,
+ scope.enclosingSourceType(),
+ (BlockScope)scope,
+ typesFound);
+ }
+
+ checkCancel();
+
+ findMemberTypes(
+ this.completionToken,
+ (ReferenceBinding) qualifiedBinding,
+ scope,
+ scope.enclosingSourceType(),
+ false,
+ false,
+ typesFound,
+ null,
+ null,
+ null,
+ false);
+ }
+ }
+ }
+
+ private boolean assistNodeIsExtendedType(ASTNode astNode, ASTNode astNodeParent) {
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=99399, don't propose final types for extension.
+ if (astNodeParent == null)
+ return false;
+ if (astNodeParent instanceof TypeDeclaration) {
+ TypeDeclaration typeDeclaration = (TypeDeclaration) astNodeParent;
+ return (typeDeclaration.superclass == astNode);
+ } else if (astNodeParent instanceof TypeParameter) {
+ TypeParameter typeParameter = (TypeParameter) astNodeParent;
+ return (typeParameter.type == astNode);
+ } else if (astNodeParent instanceof Wildcard) {
+ Wildcard wildcard = (Wildcard) astNodeParent;
+ return (wildcard.bound == astNode && wildcard.kind == Wildcard.EXTENDS);
+ }
+ return false;
+ }
+
+ private void completionOnQualifiedAllocationExpression(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
+ setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false);
+
+ CompletionOnQualifiedAllocationExpression allocExpression =
+ (CompletionOnQualifiedAllocationExpression) astNode;
+ TypeBinding[] argTypes = computeTypes(allocExpression.arguments);
+
+ ReferenceBinding ref = (ReferenceBinding) qualifiedBinding;
+
+ if (ref.problemId() == ProblemReasons.NotFound) {
+ findConstructorsFromMissingType(
+ allocExpression.type,
+ argTypes,
+ scope,
+ allocExpression);
+ } else {
+ if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)
+ && ref.isClass()
+ && !ref.isAbstract()) {
+ findConstructors(
+ ref,
+ argTypes,
+ scope,
+ allocExpression,
+ false,
+ null,
+ null,
+ null,
+ false);
+ }
+
+ checkCancel();
+
+ if (!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)
+ && !ref.isFinal()
+ && !ref.isEnum()){
+ findAnonymousType(
+ ref,
+ argTypes,
+ scope,
+ allocExpression,
+ null,
+ null,
+ null,
+ false);
+ }
+ }
+ }
+
+ private void completionOnQualifiedNameReference(ASTNode astNode, ASTNode enclosingNode, Binding qualifiedBinding,
+ Scope scope, boolean insideTypeAnnotation) {
+ this.insideQualifiedReference = true;
+ CompletionOnQualifiedNameReference ref =
+ (CompletionOnQualifiedNameReference) astNode;
+ this.completionToken = ref.completionIdentifier;
+ long completionPosition = ref.sourcePositions[ref.sourcePositions.length - 1];
+
+ if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
+ setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+ // complete field members with missing fields type
+ // class X {
+ // Missing f;
+ // void foo() {
+ // f.|
+ // }
+ // }
+ if (this.assistNodeInJavadoc == 0 &&
+ (this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
+ this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF) ||
+ this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) {
+ if(ref.tokens.length == 1) {
+ boolean foundSomeFields = findFieldsAndMethodsFromMissingFieldType(ref.tokens[0], scope, ref, insideTypeAnnotation);
+
+ if (!foundSomeFields) {
+
+ checkCancel();
+
+ findMembersFromMissingType(
+ ref.tokens[0],
+ ref.sourcePositions[0],
+ null,
+ scope,
+ ref,
+ ref.isInsideAnnotationAttribute);
+ }
+ }
+ }
+ } else if (qualifiedBinding instanceof VariableBinding) {
+ setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+ TypeBinding receiverType = ((VariableBinding) qualifiedBinding).type;
+ if (receiverType != null && (receiverType.tagBits & TagBits.HasMissingType) == 0) {
+ ObjectVector fieldsFound = new ObjectVector();
+ ObjectVector methodsFound = new ObjectVector();
+
+ findFieldsAndMethods(
+ this.completionToken,
+ receiverType.capture(scope, ref.sourceEnd),
+ scope,
+ fieldsFound,
+ methodsFound,
+ ref,
+ scope,
+ false,
+ false,
+ null,
+ null,
+ null,
+ false,
+ null,
+ -1,
+ -1);
+
+ checkCancel();
+
+ findFieldsAndMethodsFromCastedReceiver(
+ enclosingNode,
+ qualifiedBinding,
+ scope,
+ fieldsFound,
+ methodsFound,
+ ref,
+ scope,
+ ref);
+
+ } else if (this.assistNodeInJavadoc == 0 &&
+ (this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
+ this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF))) {
+ boolean proposeField = !this.requestor.isIgnored(CompletionProposal.FIELD_REF);
+ boolean proposeMethod = !this.requestor.isIgnored(CompletionProposal.METHOD_REF);
+ if (proposeField || proposeMethod) {
+ if(ref.tokens.length == 1) {
+ if (qualifiedBinding instanceof LocalVariableBinding) {
+ // complete local variable members with missing variables type
+ // class X {
+ // void foo() {
+ // Missing f;
+ // f.|
+ // }
+ // }
+ LocalVariableBinding localVariableBinding = (LocalVariableBinding) qualifiedBinding;
+ findFieldsAndMethodsFromMissingType(
+ localVariableBinding.declaration.type,
+ localVariableBinding.declaringScope,
+ ref,
+ scope);
+ } else {
+ // complete field members with missing fields type
+ // class X {
+ // Missing f;
+ // void foo() {
+ // f.|
+ // }
+ // }
+ findFieldsAndMethodsFromMissingFieldType(ref.tokens[0], scope, ref, insideTypeAnnotation);
+ }
+
+ }
+ }
+ }
+
+ } else if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
+ boolean isInsideAnnotationAttribute = ref.isInsideAnnotationAttribute;
+ ReferenceBinding receiverType = (ReferenceBinding) qualifiedBinding;
+ setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+
+ findMembers(
+ this.completionToken,
+ receiverType,
+ scope,
+ ref,
+ isInsideAnnotationAttribute,
+ null,
+ null,
+ null,
+ false);
+
+ } else if (qualifiedBinding instanceof PackageBinding) {
+
+ setSourceRange(astNode.sourceStart, (int) completionPosition);
+ setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+
+ // replace to the end of the completion identifier
+ findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
+ }
+ }
+
+ private void completionOnQualifiedTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding,
+ Scope scope) {
+ this.insideQualifiedReference = true;
+
+ CompletionOnQualifiedTypeReference ref =
+ (CompletionOnQualifiedTypeReference) astNode;
+
+ this.assistNodeIsClass = ref.isClass();
+ this.assistNodeIsException = ref.isException();
+ this.assistNodeIsInterface = ref.isInterface();
+ this.assistNodeIsConstructor = ref.isConstructorType;
+ this.assistNodeIsSuperType = ref.isSuperType();
+ this.assistNodeIsExtendedType = assistNodeIsExtendedType(astNode, astNodeParent);
+
+ this.completionToken = ref.completionIdentifier;
+ long completionPosition = ref.sourcePositions[ref.tokens.length];
+
+ // get the source positions of the completion identifier
+ if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
+ setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+ if (this.assistNodeInJavadoc == 0 &&
+ (this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) {
+ if(ref.tokens.length == 1) {
+ findMemberTypesFromMissingType(
+ ref.tokens[0],
+ ref.sourcePositions[0],
+ scope);
+ }
+ }
+ } else if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
+ if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+ setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+
+ ObjectVector typesFound = new ObjectVector();
+
+ if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
+ findExceptionFromTryStatement(
+ this.completionToken,
+ (ReferenceBinding)qualifiedBinding,
+ scope.enclosingSourceType(),
+ (BlockScope)scope,
+ typesFound);
+ }
+
+ checkCancel();
+
+ findMemberTypes(
+ this.completionToken,
+ (ReferenceBinding) qualifiedBinding,
+ scope,
+ scope.enclosingSourceType(),
+ false,
+ false,
+ typesFound,
+ null,
+ null,
+ null,
+ false);
+ }
+ } else if (qualifiedBinding instanceof PackageBinding) {
+
+ setSourceRange(astNode.sourceStart, (int) completionPosition);
+ setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+ // replace to the end of the completion identifier
+ findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
+ }
+ }
+
+ private void completionOnSingleNameReference(ASTNode astNode, ASTNode astNodeParent, Scope scope,
+ boolean insideTypeAnnotation) {
+ CompletionOnSingleNameReference singleNameReference = (CompletionOnSingleNameReference) astNode;
+ this.completionToken = singleNameReference.token;
+ SwitchStatement switchStatement = astNodeParent instanceof SwitchStatement ? (SwitchStatement) astNodeParent : null;
+ if (switchStatement != null
+ && switchStatement.expression.resolvedType != null
+ && switchStatement.expression.resolvedType.isEnum()) {
+ if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
+ this.assistNodeIsEnum = true;
+ findEnumConstantsFromSwithStatement(this.completionToken, (SwitchStatement) astNodeParent);
+ }
+ } else if (this.expectedTypesPtr > -1 && this.expectedTypes[0].isAnnotationType()) {
+ findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
+ } else {
+ if (this.expectedTypesPtr > -1) {
+ this.assistNodeIsEnum = true;
+ done : for (int i = 0; i <= this.expectedTypesPtr; i++) {
+ if (!this.expectedTypes[i].isEnum()) {
+ this.assistNodeIsEnum = false;
+ break done;
+ }
+ }
+
+ }
+ if (scope instanceof BlockScope && !this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
+ char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, singleNameReference);
+
+ findUnresolvedReference(
+ singleNameReference.sourceStart,
+ singleNameReference.sourceEnd,
+ (BlockScope)scope,
+ alreadyDefinedName);
+ }
+
+ checkCancel();
+
+ findVariablesAndMethods(
+ this.completionToken,
+ scope,
+ singleNameReference,
+ scope,
+ insideTypeAnnotation,
+ singleNameReference.isInsideAnnotationAttribute);
+//{ObjectTeams: following analyses don't apply to base/tsuper calls:
+ if (isBaseAccess(singleNameReference) || isTSuperAccess(singleNameReference))
+ return;
+// SH}
+ checkCancel();
+
+ // can be the start of a qualified type name
+ findTypesAndPackages(this.completionToken, scope, true, false, new ObjectVector());
+ if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+ if (this.completionToken != null && this.completionToken.length != 0) {
+ findKeywords(this.completionToken, singleNameReference.possibleKeywords, false, false);
+ } else {
+ findTrueOrFalseKeywords(singleNameReference.possibleKeywords);
+ }
+ }
+ if (singleNameReference.canBeExplicitConstructor && !this.requestor.isIgnored(CompletionProposal.METHOD_REF)){
+ if (CharOperation.prefixEquals(this.completionToken, Keywords.THIS, false)) {
+ ReferenceBinding ref = scope.enclosingSourceType();
+ findExplicitConstructors(Keywords.THIS, ref, (MethodScope)scope, singleNameReference);
+ } else if (CharOperation.prefixEquals(this.completionToken, Keywords.SUPER, false)) {
+ ReferenceBinding ref = scope.enclosingSourceType();
+ findExplicitConstructors(Keywords.SUPER, ref.superclass(), (MethodScope)scope, singleNameReference);
+ }
+ }
+ }
+ }
+
+ private void completionOnSingleTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope) {
+ CompletionOnSingleTypeReference singleRef = (CompletionOnSingleTypeReference) astNode;
+
+//{ObjectTeams: support baseclass decapsulation
+ if (singleRef.getBaseclassDecapsulation().isAllowed())
+ this.options.checkVisibility = false;
+// SH}
+ this.completionToken = singleRef.token;
+
+ this.assistNodeIsClass = singleRef.isClass();
+ this.assistNodeIsException = singleRef.isException();
+ this.assistNodeIsInterface = singleRef.isInterface();
+ this.assistNodeIsConstructor = singleRef.isConstructorType;
+ this.assistNodeIsSuperType = singleRef.isSuperType();
+ this.assistNodeIsExtendedType = assistNodeIsExtendedType(astNode, astNodeParent);
+
+ // can be the start of a qualified type name
+ if (qualifiedBinding == null) {
+ if (this.completionToken.length == 0 &&
+ (astNodeParent instanceof ParameterizedSingleTypeReference ||
+ astNodeParent instanceof ParameterizedQualifiedTypeReference)) {
+ this.setSourceAndTokenRange(astNode.sourceStart, astNode.sourceStart - 1, false);
+
+ findParameterizedType((TypeReference)astNodeParent, scope);
+ } else {
+ ObjectVector typesFound = new ObjectVector();
+ if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
+ findExceptionFromTryStatement(
+ this.completionToken,
+ null,
+ scope.enclosingSourceType(),
+ (BlockScope)scope,
+ typesFound);
+ }
+
+ checkCancel();
+
+ findTypesAndPackages(this.completionToken, scope, this.assistNodeIsConstructor, false, typesFound);
+ }
+ } else if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+ findMemberTypes(
+ this.completionToken,
+ (ReferenceBinding) qualifiedBinding,
+ scope,
+ scope.enclosingSourceType(),
+ false,
+ false,
+ false,
+ false,
+ !this.assistNodeIsConstructor,
+ null,
+ new ObjectVector(),
+ null,
+ null,
+ null,
+ false);
+ }
+ }
+
+ private char[][] computeAlreadyDefinedName(
+ BlockScope scope,
+ InvocationSite invocationSite) {
+ ArrayList result = new ArrayList();
+
+ boolean staticsOnly = false;
+
+ Scope currentScope = scope;
+
+ done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
+
+ switch (currentScope.kind) {
+
+ case Scope.METHOD_SCOPE :
+ // handle the error case inside an explicit constructor call (see MethodScope>>findField)
+ MethodScope methodScope = (MethodScope) currentScope;
+ staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
+
+ //$FALL-THROUGH$
+ case Scope.BLOCK_SCOPE :
+ BlockScope blockScope = (BlockScope) currentScope;
+
+ next : for (int i = 0, length = blockScope.locals.length; i < length; i++) {
+ LocalVariableBinding local = blockScope.locals[i];
+
+ if (local == null)
+ break next;
+
+ if (local.isSecret())
+ continue next;
+
+ result.add(local.name);
+ }
+ break;
+
+ case Scope.CLASS_SCOPE :
+ ClassScope classScope = (ClassScope) currentScope;
+ SourceTypeBinding enclosingType = classScope.referenceContext.binding;
+ computeAlreadyDefinedName(
+ enclosingType,
+ classScope,
+ staticsOnly,
+ invocationSite,
+ result);
+ staticsOnly |= enclosingType.isStatic();
+ break;
+
+ case Scope.COMPILATION_UNIT_SCOPE :
+ break done1;
+ }
+ currentScope = currentScope.parent;
+ }
+
+ if (result.size() == 0) return CharOperation.NO_CHAR_CHAR;
+
+ return (char[][])result.toArray(new char[result.size()][]);
+ }
+
+ private void computeAlreadyDefinedName(
+ FieldBinding[] fields,
+ Scope scope,
+ boolean onlyStaticFields,
+ ReferenceBinding receiverType,
+ InvocationSite invocationSite,
+ ArrayList result) {
+
+ next : for (int f = fields.length; --f >= 0;) {
+ FieldBinding field = fields[f];
+
+ if (field.isSynthetic()) continue next;
+
+ if (onlyStaticFields && !field.isStatic()) continue next;
+
+ if (!field.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
+
+ result.add(field.name);
+ }
+ }
+
+ private void computeAlreadyDefinedName(
+ SourceTypeBinding receiverType,
+ ClassScope scope,
+ boolean onlyStaticFields,
+ InvocationSite invocationSite,
+ ArrayList result) {
+
+ ReferenceBinding currentType = receiverType;
+ ReferenceBinding[] interfacesToVisit = null;
+ int nextPosition = 0;
+ do {
+ ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
+ if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
+ if (interfacesToVisit == null) {
+ interfacesToVisit = itsInterfaces;
+ nextPosition = interfacesToVisit.length;
+ } else {
+ int itsLength = itsInterfaces.length;
+ if (nextPosition + itsLength >= interfacesToVisit.length)
+ System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+ nextInterface : for (int a = 0; a < itsLength; a++) {
+ ReferenceBinding next = itsInterfaces[a];
+ for (int b = 0; b < nextPosition; b++)
+ if (next == interfacesToVisit[b]) continue nextInterface;
+ interfacesToVisit[nextPosition++] = next;
+ }
+ }
+ }
+
+ FieldBinding[] fields = currentType.availableFields();
+ if(fields != null && fields.length > 0) {
+ computeAlreadyDefinedName(
+ fields,
+ scope,
+ onlyStaticFields,
+ receiverType,
+ invocationSite,
+ result);
+ }
+ currentType = currentType.superclass();
+ } while ( currentType != null);
+
+ if (interfacesToVisit != null) {
+ for (int i = 0; i < nextPosition; i++) {
+ ReferenceBinding anInterface = interfacesToVisit[i];
+ FieldBinding[] fields = anInterface.availableFields();
+ if(fields != null) {
+ computeAlreadyDefinedName(
+ fields,
+ scope,
+ onlyStaticFields,
+ receiverType,
+ invocationSite,
+ result);
+ }
+
+ ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
+ if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
+ int itsLength = itsInterfaces.length;
+ if (nextPosition + itsLength >= interfacesToVisit.length)
+ System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+ nextInterface : for (int a = 0; a < itsLength; a++) {
+ ReferenceBinding next = itsInterfaces[a];
+ for (int b = 0; b < nextPosition; b++)
+ if (next == interfacesToVisit[b]) continue nextInterface;
+ interfacesToVisit[nextPosition++] = next;
+ }
+ }
+ }
+ }
+ }
+
+ int computeBaseRelevance(){
+ return R_DEFAULT;
+ }
+
+ private void computeExpectedTypes(ASTNode parent, ASTNode node, Scope scope){
+
+ // default filter
+ this.expectedTypesFilter = SUBTYPE;
+ this.hasJavaLangObjectAsExpectedType = false;
+
+ // find types from parent
+ if(parent instanceof AbstractVariableDeclaration && !(parent instanceof TypeParameter)) {
+ AbstractVariableDeclaration variable = (AbstractVariableDeclaration)parent;
+ TypeBinding binding = variable.type.resolvedType;
+ if(binding != null) {
+ if(!(variable.initialization instanceof ArrayInitializer)) {
+ addExpectedType(binding, scope);
+ }
+ }
+ } else if(parent instanceof Assignment) {
+ TypeBinding binding = ((Assignment)parent).lhs.resolvedType;
+ if(binding != null) {
+ addExpectedType(binding, scope);
+ }
+ } else if(parent instanceof ReturnStatement) {
+ if(scope.methodScope().referenceContext instanceof AbstractMethodDeclaration) {
+ MethodBinding methodBinding = ((AbstractMethodDeclaration) scope.methodScope().referenceContext).binding;
+ TypeBinding binding = methodBinding == null ? null : methodBinding.returnType;
+ if(binding != null) {
+ addExpectedType(binding, scope);
+ }
+ }
+ } else if(parent instanceof CastExpression) {
+ Expression e = ((CastExpression)parent).type;
+ TypeBinding binding = e.resolvedType;
+ if(binding != null){
+ addExpectedType(binding, scope);
+ this.expectedTypesFilter = SUBTYPE | SUPERTYPE;
+ }
+ } else if(parent instanceof MessageSend) {
+ MessageSend messageSend = (MessageSend) parent;
+
+ if(messageSend.actualReceiverType instanceof ReferenceBinding) {
+ ReferenceBinding binding = (ReferenceBinding)messageSend.actualReceiverType;
+ boolean isStatic = messageSend.receiver.isTypeReference();
+
+ while(binding != null) {
+ computeExpectedTypesForMessageSend(
+ binding,
+ messageSend.selector,
+ messageSend.arguments,
+ (ReferenceBinding)messageSend.actualReceiverType,
+ scope,
+ messageSend,
+ isStatic);
+ computeExpectedTypesForMessageSendForInterface(
+ binding,
+ messageSend.selector,
+ messageSend.arguments,
+ (ReferenceBinding)messageSend.actualReceiverType,
+ scope,
+ messageSend,
+ isStatic);
+ binding = binding.superclass();
+ }
+ }
+ } else if(parent instanceof AllocationExpression) {
+ AllocationExpression allocationExpression = (AllocationExpression) parent;
+
+ ReferenceBinding binding = (ReferenceBinding)allocationExpression.type.resolvedType;
+
+ if(binding != null) {
+ computeExpectedTypesForAllocationExpression(
+ binding,
+ allocationExpression.arguments,
+ scope,
+ allocationExpression);
+ }
+ } else if(parent instanceof OperatorExpression) {
+ int operator = (parent.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT;
+ if(parent instanceof ConditionalExpression) {
+ // for future use
+ } else if(parent instanceof InstanceOfExpression) {
+ InstanceOfExpression e = (InstanceOfExpression) parent;
+ TypeBinding binding = e.expression.resolvedType;
+ if(binding != null){
+ addExpectedType(binding, scope);
+ this.expectedTypesFilter = SUBTYPE | SUPERTYPE;
+ }
+ } else if(parent instanceof BinaryExpression) {
+ BinaryExpression binaryExpression = (BinaryExpression) parent;
+ switch(operator) {
+ case OperatorIds.EQUAL_EQUAL :
+ // expected type is not relevant in this case
+ TypeBinding binding = binaryExpression.left.resolvedType;
+ if (binding != null) {
+ addExpectedType(binding, scope);
+ this.expectedTypesFilter = SUBTYPE | SUPERTYPE;
+ }
+ break;
+ case OperatorIds.PLUS :
+ addExpectedType(TypeBinding.SHORT, scope);
+ addExpectedType(TypeBinding.INT, scope);
+ addExpectedType(TypeBinding.LONG, scope);
+ addExpectedType(TypeBinding.FLOAT, scope);
+ addExpectedType(TypeBinding.DOUBLE, scope);
+ addExpectedType(TypeBinding.CHAR, scope);
+ addExpectedType(TypeBinding.BYTE, scope);
+ addExpectedType(scope.getJavaLangString(), scope);
+ break;
+ case OperatorIds.AND_AND :
+ case OperatorIds.OR_OR :
+ case OperatorIds.XOR :
+ addExpectedType(TypeBinding.BOOLEAN, scope);
+ break;
+ default :
+ addExpectedType(TypeBinding.SHORT, scope);
+ addExpectedType(TypeBinding.INT, scope);
+ addExpectedType(TypeBinding.LONG, scope);
+ addExpectedType(TypeBinding.FLOAT, scope);
+ addExpectedType(TypeBinding.DOUBLE, scope);
+ addExpectedType(TypeBinding.CHAR, scope);
+ addExpectedType(TypeBinding.BYTE, scope);
+ break;
+ }
+ if(operator == OperatorIds.LESS) {
+ if(binaryExpression.left instanceof SingleNameReference){
+ SingleNameReference name = (SingleNameReference) binaryExpression.left;
+ Binding b = scope.getBinding(name.token, Binding.VARIABLE | Binding.TYPE, name, false);
+ if(b instanceof ReferenceBinding) {
+ TypeVariableBinding[] typeVariableBindings =((ReferenceBinding)b).typeVariables();
+ if(typeVariableBindings != null && typeVariableBindings.length > 0) {
+ addExpectedType(typeVariableBindings[0].firstBound, scope);
+ }
+
+ }
+ }
+ }
+ } else if(parent instanceof UnaryExpression) {
+ switch(operator) {
+ case OperatorIds.NOT :
+ addExpectedType(TypeBinding.BOOLEAN, scope);
+ break;
+ case OperatorIds.TWIDDLE :
+ addExpectedType(TypeBinding.SHORT, scope);
+ addExpectedType(TypeBinding.INT, scope);
+ addExpectedType(TypeBinding.LONG, scope);
+ addExpectedType(TypeBinding.CHAR, scope);
+ addExpectedType(TypeBinding.BYTE, scope);
+ break;
+ case OperatorIds.PLUS :
+ case OperatorIds.MINUS :
+ case OperatorIds.PLUS_PLUS :
+ case OperatorIds.MINUS_MINUS :
+ addExpectedType(TypeBinding.SHORT, scope);
+ addExpectedType(TypeBinding.INT, scope);
+ addExpectedType(TypeBinding.LONG, scope);
+ addExpectedType(TypeBinding.FLOAT, scope);
+ addExpectedType(TypeBinding.DOUBLE, scope);
+ addExpectedType(TypeBinding.CHAR, scope);
+ addExpectedType(TypeBinding.BYTE, scope);
+ break;
+ }
+ }
+ } else if(parent instanceof ArrayReference) {
+ addExpectedType(TypeBinding.SHORT, scope);
+ addExpectedType(TypeBinding.INT, scope);
+ addExpectedType(TypeBinding.LONG, scope);
+ } else if(parent instanceof ParameterizedSingleTypeReference) {
+ ParameterizedSingleTypeReference ref = (ParameterizedSingleTypeReference) parent;
+ TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables();
+ int length = ref.typeArguments == null ? 0 : ref.typeArguments.length;
+ if(typeVariables != null && typeVariables.length >= length) {
+ int index = length - 1;
+ while(index > -1 && ref.typeArguments[index] != node) index--;
+
+ TypeBinding bound = typeVariables[index].firstBound;
+ addExpectedType(bound == null ? scope.getJavaLangObject() : bound, scope);
+ }
+ } else if(parent instanceof ParameterizedQualifiedTypeReference) {
+ ParameterizedQualifiedTypeReference ref = (ParameterizedQualifiedTypeReference) parent;
+ TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables();
+ TypeReference[][] arguments = ref.typeArguments;
+ if(typeVariables != null) {
+ int iLength = arguments == null ? 0 : arguments.length;
+ done: for (int i = 0; i < iLength; i++) {
+ int jLength = arguments[i] == null ? 0 : arguments[i].length;
+ for (int j = 0; j < jLength; j++) {
+ if(arguments[i][j] == node && typeVariables.length > j) {
+ TypeBinding bound = typeVariables[j].firstBound;
+ addExpectedType(bound == null ? scope.getJavaLangObject() : bound, scope);
+ break done;
+ }
+ }
+ }
+ }
+ } else if(parent instanceof MemberValuePair) {
+ MemberValuePair memberValuePair = (MemberValuePair) parent;
+ if(memberValuePair.binding != null) {
+ addExpectedType(memberValuePair.binding.returnType, scope);
+ }
+ } else if (parent instanceof NormalAnnotation) {
+ NormalAnnotation annotation = (NormalAnnotation) parent;
+ MemberValuePair[] memberValuePairs = annotation.memberValuePairs();
+ if(memberValuePairs == null || memberValuePairs.length == 0) {
+ if(annotation.resolvedType instanceof ReferenceBinding) {
+ MethodBinding[] methodBindings =
+ ((ReferenceBinding)annotation.resolvedType).availableMethods();
+ if (methodBindings != null &&
+ methodBindings.length > 0 &&
+ CharOperation.equals(methodBindings[0].selector, VALUE)) {
+ boolean canBeSingleMemberAnnotation = true;
+ done : for (int i = 1; i < methodBindings.length; i++) {
+ if((methodBindings[i].modifiers & ClassFileConstants.AccAnnotationDefault) == 0) {
+ canBeSingleMemberAnnotation = false;
+ break done;
+ }
+ }
+ if (canBeSingleMemberAnnotation) {
+ this.assistNodeCanBeSingleMemberAnnotation = canBeSingleMemberAnnotation;
+ addExpectedType(methodBindings[0].returnType, scope);
+ }
+ }
+ }
+ }
+ } else if (parent instanceof TryStatement) {
+ boolean isException = false;
+ if (node instanceof CompletionOnSingleTypeReference) {
+ isException = ((CompletionOnSingleTypeReference)node).isException();
+ } else if (node instanceof CompletionOnQualifiedTypeReference) {
+ isException = ((CompletionOnQualifiedTypeReference)node).isException();
+ } else if (node instanceof CompletionOnParameterizedQualifiedTypeReference) {
+ isException = ((CompletionOnParameterizedQualifiedTypeReference)node).isException();
+ }
+ if (isException) {
+ ThrownExceptionFinder thrownExceptionFinder = new ThrownExceptionFinder();
+ ReferenceBinding[] bindings = thrownExceptionFinder.find((TryStatement) parent, (BlockScope)scope);
+ if (bindings != null && bindings.length > 0) {
+ for (int i = 0; i < bindings.length; i++) {
+ addExpectedType(bindings[i], scope);
+ }
+ this.expectedTypesFilter = SUPERTYPE;
+ }
+ }
+ } else if (parent instanceof SwitchStatement) {
+ SwitchStatement switchStatement = (SwitchStatement) parent;
+ if (switchStatement.expression != null &&
+ switchStatement.expression.resolvedType != null) {
+ addExpectedType(switchStatement.expression.resolvedType, scope);
+ }
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=253008, flag boolean as the expected
+ // type if we are completing inside if(), for (; ;), while() and do while()
+ } else if (parent instanceof WhileStatement) { // covers both while and do-while loops
+ addExpectedType(TypeBinding.BOOLEAN, scope);
+ } else if (parent instanceof IfStatement) {
+ addExpectedType(TypeBinding.BOOLEAN, scope);
+ } else if (parent instanceof AssertStatement) {
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=274466
+ // If the assertExpression is same as the node , then the assistNode is the conditional part of the assert statement
+ AssertStatement assertStatement = (AssertStatement) parent;
+ if (assertStatement.assertExpression == node) {
+ addExpectedType(TypeBinding.BOOLEAN, scope);
+ }
+ } else if (parent instanceof ForStatement) { // astNodeParent set to ForStatement only for the condition
+ addExpectedType(TypeBinding.BOOLEAN, scope);
+
+ // Expected types for javadoc
+ } else if (parent instanceof Javadoc) {
+ if (scope.kind == Scope.METHOD_SCOPE) {
+ MethodScope methodScope = (MethodScope) scope;
+ AbstractMethodDeclaration methodDecl = methodScope.referenceMethod();
+ if (methodDecl != null && methodDecl.binding != null) {
+ ReferenceBinding[] exceptions = methodDecl.binding.thrownExceptions;
+ if (exceptions != null) {
+ for (int i = 0; i < exceptions.length; i++) {
+ addExpectedType(exceptions[i], scope);
+ }
+ }
+ }
+ }
+ }
+
+ if(this.expectedTypesPtr + 1 != this.expectedTypes.length) {
+ System.arraycopy(this.expectedTypes, 0, this.expectedTypes = new TypeBinding[this.expectedTypesPtr + 1], 0, this.expectedTypesPtr + 1);
+ }
+ }
+
+ private void computeExpectedTypesForAllocationExpression(
+ ReferenceBinding binding,
+ Expression[] arguments,
+ Scope scope,
+ InvocationSite invocationSite) {
+
+ MethodBinding[] methods = binding.availableMethods();
+ nextMethod : for (int i = 0; i < methods.length; i++) {
+ MethodBinding method = methods[i];
+
+ if (!method.isConstructor()) continue nextMethod;
+
+ if (method.isSynthetic()) continue nextMethod;
+
+ if (this.options.checkVisibility && !method.canBeSeenBy(invocationSite, scope)) continue nextMethod;
+
+ TypeBinding[] parameters = method.parameters;
+ if(parameters.length < arguments.length)
+ continue nextMethod;
+
+ int length = arguments.length - 1;
+
+ for (int j = 0; j < length; j++) {
+ Expression argument = arguments[j];
+ TypeBinding argType = argument.resolvedType;
+ if(argType != null && !argType.isCompatibleWith(parameters[j]))
+ continue nextMethod;
+ }
+
+ TypeBinding expectedType = method.parameters[arguments.length - 1];
+ if(expectedType != null) {
+ addExpectedType(expectedType, scope);
+ }
+ }
+ }
+ private void computeExpectedTypesForMessageSend(
+ ReferenceBinding binding,
+ char[] selector,
+ Expression[] arguments,
+ ReferenceBinding receiverType,
+ Scope scope,
+ InvocationSite invocationSite,
+ boolean isStatic) {
+
+ MethodBinding[] methods = binding.availableMethods();
+ nextMethod : for (int i = 0; i < methods.length; i++) {
+ MethodBinding method = methods[i];
+
+ if (method.isSynthetic()) continue nextMethod;
+
+ if (method.isDefaultAbstract()) continue nextMethod;
+
+ if (method.isConstructor()) continue nextMethod;
+
+ if (isStatic && !method.isStatic()) continue nextMethod;
+
+ if (this.options.checkVisibility && !method.canBeSeenBy(receiverType, invocationSite, scope)) continue nextMethod;
+
+ if(!CharOperation.equals(method.selector, selector)) continue nextMethod;
+
+ TypeBinding[] parameters = method.parameters;
+ if(parameters.length < arguments.length)
+ continue nextMethod;
+
+ int length = arguments.length - 1;
+
+ for (int j = 0; j < length; j++) {
+ Expression argument = arguments[j];
+ TypeBinding argType = argument.resolvedType;
+ if(argType != null && !argType.isCompatibleWith(parameters[j]))
+ continue nextMethod;
+ }
+
+ TypeBinding expectedType = method.parameters[arguments.length - 1];
+ if(expectedType != null) {
+ addExpectedType(expectedType, scope);
+ }
+ }
+ }
+ private void computeExpectedTypesForMessageSendForInterface(
+ ReferenceBinding binding,
+ char[] selector,
+ Expression[] arguments,
+ ReferenceBinding receiverType,
+ Scope scope,
+ InvocationSite invocationSite,
+ boolean isStatic) {
+
+ ReferenceBinding[] itsInterfaces = binding.superInterfaces();
+ if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
+ ReferenceBinding[] interfacesToVisit = itsInterfaces;
+ int nextPosition = interfacesToVisit.length;
+
+ for (int i = 0; i < nextPosition; i++) {
+ ReferenceBinding currentType = interfacesToVisit[i];
+ computeExpectedTypesForMessageSend(
+ currentType,
+ selector,
+ arguments,
+ receiverType,
+ scope,
+ invocationSite,
+ isStatic);
+
+ if ((itsInterfaces = currentType.superInterfaces()) != Binding.NO_SUPERINTERFACES) {
+ int itsLength = itsInterfaces.length;
+ if (nextPosition + itsLength >= interfacesToVisit.length)
+ System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+ nextInterface : for (int a = 0; a < itsLength; a++) {
+ ReferenceBinding next = itsInterfaces[a];
+ for (int b = 0; b < nextPosition; b++)
+ if (next == interfacesToVisit[b]) continue nextInterface;
+ interfacesToVisit[nextPosition++] = next;
+ }
+ }
+ }
+ }
+ }
+
+ private Scope computeForbiddenBindings(ASTNode astNode, ASTNode astNodeParent, Scope scope) {
+ this.forbbidenBindingsFilter = NONE;
+ if(scope instanceof ClassScope) {
+ TypeDeclaration typeDeclaration = ((ClassScope)scope).referenceContext;
+ if(typeDeclaration.superclass == astNode) {
+ addForbiddenBindings(typeDeclaration.binding);
+ addForbiddenBindingsForMemberTypes(typeDeclaration);
+//{ObjectTeams: role may not extend enclosing!
+ if (typeDeclaration.binding.isRole()) {
+ ReferenceBinding currentOuter = typeDeclaration.binding.enclosingType();
+ while (currentOuter != null) {
+ addForbiddenBindings(currentOuter);
+ currentOuter = currentOuter.enclosingType();
+ }
+ }
+// SH}
+ return scope.parent;
+ }
+//{ObjectTeams: similar for playedBy:
+ if(typeDeclaration.baseclass == astNode) {
+ ReferenceBinding ifcBinding;
+ RoleModel roleModel = typeDeclaration.getRoleModel();
+ if ((ifcBinding= roleModel.getInterfacePartBinding()) != null)
+ addForbiddenBaseclasses(ifcBinding);
+ else
+ addForbiddenBaseclasses(typeDeclaration.binding);
+ ReferenceBinding currentOuter = typeDeclaration.binding.enclosingType();
+ while (currentOuter != null) {
+ this.addForbiddenBindings(currentOuter);
+ currentOuter = currentOuter.enclosingType();
+ }
+ return scope.parent;
+ }
+// SH}
+ TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
+ int length = superInterfaces == null ? 0 : superInterfaces.length;
+ int astNodeIndex = -1;
+ for (int i = 0; i < length; i++) {
+ if(superInterfaces[i] == astNode) {
+ addForbiddenBindings(typeDeclaration.binding);
+ addForbiddenBindingsForMemberTypes(typeDeclaration);
+ astNodeIndex = i;
+ break;
+ }
+ }
+ if (astNodeIndex >= 0) {
+ // Need to loop only up to astNodeIndex as the rest will be undefined.
+ for (int i = 0; i < astNodeIndex; i++) {
+ addForbiddenBindings(superInterfaces[i].resolvedType);
+ }
+ return scope.parent;
+ }
+ } else {
+ if (astNodeParent != null && astNodeParent instanceof TryStatement) {
+ boolean isException = false;
+ if (astNode instanceof CompletionOnSingleTypeReference) {
+ isException = ((CompletionOnSingleTypeReference)astNode).isException();
+ } else if (astNode instanceof CompletionOnQualifiedTypeReference) {
+ isException = ((CompletionOnQualifiedTypeReference)astNode).isException();
+ } else if (astNode instanceof CompletionOnParameterizedQualifiedTypeReference) {
+ isException = ((CompletionOnParameterizedQualifiedTypeReference)astNode).isException();
+ }
+ if (isException) {
+ Argument[] catchArguments = ((TryStatement) astNodeParent).catchArguments;
+ int length = catchArguments == null ? 0 : catchArguments.length;
+ for (int i = 0; i < length; i++) {
+ TypeBinding caughtException = catchArguments[i].type.resolvedType;
+ if (caughtException != null) {
+ addForbiddenBindings(caughtException);
+ this.knownTypes.put(CharOperation.concat(caughtException.qualifiedPackageName(), caughtException.qualifiedSourceName(), '.'), KNOWN_TYPE_WITH_KNOWN_CONSTRUCTORS);
+ }
+ }
+ this.forbbidenBindingsFilter = SUBTYPE;
+ }
+ }
+ }
+// else if(scope instanceof MethodScope) {
+// MethodScope methodScope = (MethodScope) scope;
+// if(methodScope.insideTypeAnnotation) {
+// return methodScope.parent.parent;
+// }
+// }
+ return scope;
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=270437
+ private void addForbiddenBindingsForMemberTypes(TypeDeclaration typeDeclaration) {
+ TypeDeclaration[] memberTypes = typeDeclaration.memberTypes;
+ int memberTypesLen = memberTypes == null ? 0 : memberTypes.length;
+ for (int i = 0; i < memberTypesLen; i++) {
+ addForbiddenBindings(memberTypes[i].binding);
+ addForbiddenBindingsForMemberTypes(memberTypes[i]);
+ }
+ }
+
+ private char[] computePrefix(SourceTypeBinding declarationType, SourceTypeBinding invocationType, boolean isStatic){
+
+ StringBuffer completion = new StringBuffer(10);
+
+ if (isStatic) {
+ completion.append(declarationType.sourceName());
+
+ } else if (declarationType == invocationType) {
+ completion.append(THIS);
+
+ } else {
+
+ if (!declarationType.isNestedType()) {
+
+ completion.append(declarationType.sourceName());
+ completion.append('.');
+ completion.append(THIS);
+
+ } else if (!declarationType.isAnonymousType()) {
+
+ completion.append(declarationType.sourceName());
+ completion.append('.');
+ completion.append(THIS);
+
+ }
+ }
+
+ return completion.toString().toCharArray();
+ }
+
+ private int computeRelevanceForAnnotation(){
+ if(this.assistNodeIsAnnotation) {
+ return R_ANNOTATION;
+ }
+ return 0;
+ }
+
+ private int computeRelevanceForAnnotationTarget(TypeBinding typeBinding){
+ if (this.assistNodeIsAnnotation &&
+ (this.targetedElement & TagBits.AnnotationTargetMASK) != 0) {
+ long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK;
+ if(target == 0 || (target & this.targetedElement) != 0) {
+ return R_TARGET;
+ }
+ }
+ return 0;
+ }
+ int computeRelevanceForCaseMatching(char[] token, char[] proposalName){
+ if (this.options.camelCaseMatch) {
+ if(CharOperation.equals(token, proposalName, true /* do not ignore case */)) {
+ return R_CASE + R_EXACT_NAME;
+ } else if (CharOperation.prefixEquals(token, proposalName, true /* do not ignore case */)) {
+ return R_CASE;
+ } else if (CharOperation.camelCaseMatch(token, proposalName)){
+ return R_CAMEL_CASE;
+ } else if(CharOperation.equals(token, proposalName, false /* ignore case */)) {
+ return R_EXACT_NAME;
+ }
+ } else if (CharOperation.prefixEquals(token, proposalName, true /* do not ignore case */)) {
+ if(CharOperation.equals(token, proposalName, true /* do not ignore case */)) {
+ return R_CASE + R_EXACT_NAME;
+ } else {
+ return R_CASE;
+ }
+ } else if(CharOperation.equals(token, proposalName, false /* ignore case */)) {
+ return R_EXACT_NAME;
+ }
+ return 0;
+ }
+
+ private int computeRelevanceForClass(){
+ if(this.assistNodeIsClass) {
+ return R_CLASS;
+ }
+ return 0;
+ }
+
+ private int computeRelevanceForEnum(){
+ if(this.assistNodeIsEnum) {
+ return R_ENUM;
+ }
+ return 0;
+ }
+
+ private int computeRelevanceForEnumConstant(TypeBinding proposalType){
+ if(this.assistNodeIsEnum &&
+ proposalType != null &&
+ this.expectedTypes != null) {
+ for (int i = 0; i <= this.expectedTypesPtr; i++) {
+ if (proposalType.isEnum() &&
+ proposalType == this.expectedTypes[i]) {
+ return R_ENUM + R_ENUM_CONSTANT;
+ }
+
+ }
+ }
+ return 0;
+ }
+
+ private int computeRelevanceForException(){
+ if (this.assistNodeIsException) {
+ return R_EXCEPTION;
+ }
+ return 0;
+ }
+
+ private int computeRelevanceForException(char[] proposalName){
+
+ if((this.assistNodeIsException || (this.assistNodeInJavadoc & CompletionOnJavadoc.EXCEPTION) != 0 )&&
+ (CharOperation.match(EXCEPTION_PATTERN, proposalName, false) ||
+ CharOperation.match(ERROR_PATTERN, proposalName, false))) {
+ return R_EXCEPTION;
+ }
+ return 0;
+ }
+
+ private int computeRelevanceForExpectingType(char[] packageName, char[] typeName){
+ if(this.expectedTypes != null) {
+ for (int i = 0; i <= this.expectedTypesPtr; i++) {
+ if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), packageName) &&
+ CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), typeName)) {
+ return R_EXACT_EXPECTED_TYPE;
+ }
+ }
+ if(this.hasJavaLangObjectAsExpectedType) {
+ return R_EXPECTED_TYPE;
+ }
+ }
+ return 0;
+ }
+
+ private int computeRelevanceForExpectingType(TypeBinding proposalType){
+ if(this.expectedTypes != null && proposalType != null) {
+ int relevance = 0;
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=271296
+ // If there is at least one expected type, then void proposal types attract a degraded relevance.
+ if (proposalType == TypeBinding.VOID && this.expectedTypesPtr >=0) {
+ return R_VOID;
+ }
+ for (int i = 0; i <= this.expectedTypesPtr; i++) {
+ if((this.expectedTypesFilter & SUBTYPE) != 0
+ && proposalType.isCompatibleWith(this.expectedTypes[i])) {
+
+ if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), proposalType.qualifiedPackageName()) &&
+ CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), proposalType.qualifiedSourceName())) {
+ return R_EXACT_EXPECTED_TYPE;
+ }
+
+ relevance = R_EXPECTED_TYPE;
+ }
+ if((this.expectedTypesFilter & SUPERTYPE) != 0
+ && this.expectedTypes[i].isCompatibleWith(proposalType)) {
+
+ if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), proposalType.qualifiedPackageName()) &&
+ CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), proposalType.qualifiedSourceName())) {
+ return R_EXACT_EXPECTED_TYPE;
+ }
+
+ relevance = R_EXPECTED_TYPE;
+ }
+ // Bug 84720 - [1.5][assist] proposal ranking by return value should consider auto(un)boxing
+ // Just ensuring that the unitScope is not null, even though it's an unlikely case.
+ if (this.unitScope != null && this.unitScope.isBoxingCompatibleWith(proposalType, this.expectedTypes[i])) {
+ relevance = R_EXPECTED_TYPE;
+ }
+ }
+ return relevance;
+ }
+ return 0;
+ }
+
+ private int computeRelevanceForInheritance(ReferenceBinding receiverType, ReferenceBinding declaringClass) {
+ if (receiverType == declaringClass) return R_NON_INHERITED;
+ return 0;
+ }
+
+ int computeRelevanceForInterestingProposal(){
+ return computeRelevanceForInterestingProposal(null);
+ }
+
+ private int computeRelevanceForInterestingProposal(Binding binding){
+ if(this.uninterestingBindings != null) {
+ for (int i = 0; i <= this.uninterestingBindingsPtr; i++) {
+ if(this.uninterestingBindings[i] == binding) {
+ return 0;
+ }
+ }
+ }
+ return R_INTERESTING;
+ }
+
+ private int computeRelevanceForInterface(){
+ if(this.assistNodeIsInterface) {
+ return R_INTERFACE;
+ }
+ return 0;
+ }
+
+ private int computeRelevanceForMissingElements(boolean hasProblems) {
+ if (!hasProblems) {
+ return R_NO_PROBLEMS;
+ }
+ return 0;
+ }
+ int computeRelevanceForQualification(boolean prefixRequired) {
+ if(!prefixRequired && !this.insideQualifiedReference) {
+ return R_UNQUALIFIED;
+ }
+
+ if(prefixRequired && this.insideQualifiedReference) {
+ return R_QUALIFIED;
+ }
+ return 0;
+ }
+
+ int computeRelevanceForResolution(){
+ return computeRelevanceForResolution(true);
+ }
+
+ int computeRelevanceForResolution(boolean isResolved){
+ if (isResolved) {
+ return R_RESOLVED;
+ }
+ return 0;
+ }
+
+ int computeRelevanceForRestrictions(int accessRuleKind) {
+ if(accessRuleKind == IAccessRule.K_ACCESSIBLE) {
+ return R_NON_RESTRICTED;
+ }
+ return 0;
+ }
+
+ private int computeRelevanceForStatic(boolean onlyStatic, boolean isStatic) {
+ if(this.insideQualifiedReference && !onlyStatic && !isStatic) {
+ return R_NON_STATIC;
+ }
+ return 0;
+ }
+
+ private long computeTargetedElement(CompletionOnAnnotationOfType fakeNode) {
+ ASTNode annotatedElement = fakeNode.potentialAnnotatedNode;
+
+ if (annotatedElement instanceof TypeDeclaration) {
+ TypeDeclaration annotatedTypeDeclaration = (TypeDeclaration) annotatedElement;
+ if (TypeDeclaration.kind(annotatedTypeDeclaration.modifiers) == TypeDeclaration.ANNOTATION_TYPE_DECL) {
+ return TagBits.AnnotationForAnnotationType | TagBits.AnnotationForType;
+ }
+ return TagBits.AnnotationForType;
+ } else if (annotatedElement instanceof FieldDeclaration) {
+ if (fakeNode.isParameter) {
+ return TagBits.AnnotationForParameter;
+ }
+ return TagBits.AnnotationForField;
+ } else if (annotatedElement instanceof MethodDeclaration) {
+ return TagBits.AnnotationForMethod;
+ } else if (annotatedElement instanceof Argument) {
+ return TagBits.AnnotationForParameter;
+ } else if (annotatedElement instanceof ConstructorDeclaration) {
+ return TagBits.AnnotationForConstructor;
+ } else if (annotatedElement instanceof LocalDeclaration) {
+ return TagBits.AnnotationForLocalVariable;
+ } else if (annotatedElement instanceof ImportReference) {
+ return TagBits.AnnotationForPackage;
+ }
+ return 0;
+ }
+ private TypeBinding[] computeTypes(Expression[] arguments) {
+ if (arguments == null) return null;
+ int argsLength = arguments.length;
+ TypeBinding[] argTypes = new TypeBinding[argsLength];
+ for (int a = argsLength; --a >= 0;) {
+ argTypes[a] = arguments[a].resolvedType;
+ }
+ return argTypes;
+ }
+
+ private TypeBinding[] computeTypesIfCorrect(Expression[] arguments) {
+ if (arguments == null) return null;
+ int argsLength = arguments.length;
+ TypeBinding[] argTypes = new TypeBinding[argsLength];
+ for (int a = argsLength; --a >= 0;) {
+ TypeBinding typeBinding = arguments[a].resolvedType;
+ if(typeBinding == null || !typeBinding.isValidBinding()) return null;
+ argTypes[a] = typeBinding;
+ }
+ return argTypes;
+ }
+
+ private void computeUninterestingBindings(ASTNode parent, Scope scope){
+ if(parent instanceof LocalDeclaration) {
+ addUninterestingBindings(((LocalDeclaration)parent).binding);
+ } else if (parent instanceof FieldDeclaration) {
+ addUninterestingBindings(((FieldDeclaration)parent).binding);
+ }
+ }
+
+ private char[] createImportCharArray(char[] importedElement, boolean isStatic, boolean onDemand) {
+ char[] result = IMPORT;
+ if (isStatic) {
+ result = CharOperation.concat(result, STATIC, ' ');
+ }
+ result = CharOperation.concat(result, importedElement, ' ');
+ if (onDemand) {
+ result = CharOperation.concat(result, ON_DEMAND);
+ }
+ return CharOperation.concat(result, IMPORT_END);
+ }
+
+ private void createMethod(MethodBinding method, char[][] parameterPackageNames, char[][] parameterTypeNames, char[][] parameterNames, Scope scope, StringBuffer completion) {
+ //// Modifiers
+ // flush uninteresting modifiers
+ int insertedModifiers = method.modifiers & ~(ClassFileConstants.AccNative | ClassFileConstants.AccAbstract);
+ if(insertedModifiers != ClassFileConstants.AccDefault){
+ ASTNode.printModifiers(insertedModifiers, completion);
+ }
+
+ //// Type parameters
+
+ TypeVariableBinding[] typeVariableBindings = method.typeVariables;
+ if(typeVariableBindings != null && typeVariableBindings.length != 0) {
+ completion.append('<');
+ for (int i = 0; i < typeVariableBindings.length; i++) {
+ if(i != 0) {
+ completion.append(',');
+ completion.append(' ');
+ }
+ createTypeVariable(typeVariableBindings[i], scope, completion);
+ }
+ completion.append('>');
+ completion.append(' ');
+ }
+
+ //// Return type
+ createType(method.returnType, scope, completion);
+ completion.append(' ');
+
+ //// Selector
+ completion.append(method.selector);
+
+ completion.append('(');
+
+ ////Parameters
+ TypeBinding[] parameterTypes = method.parameters;
+ int length = parameterTypes.length;
+ for (int i = 0; i < length; i++) {
+ if(i != 0) {
+ completion.append(',');
+ completion.append(' ');
+ }
+ createType(parameterTypes[i], scope, completion);
+ completion.append(' ');
+ if(parameterNames != null){
+ completion.append(parameterNames[i]);
+ } else {
+ completion.append('%');
+ }
+ }
+
+ completion.append(')');
+
+ //// Exceptions
+ ReferenceBinding[] exceptions = method.thrownExceptions;
+
+ if (exceptions != null && exceptions.length > 0){
+ completion.append(' ');
+ completion.append(THROWS);
+ completion.append(' ');
+ for(int i = 0; i < exceptions.length ; i++){
+ if(i != 0) {
+ completion.append(' ');
+ completion.append(',');
+ }
+ createType(exceptions[i], scope, completion);
+ }
+ }
+ }
+
+ protected InternalCompletionProposal createProposal(int kind, int completionOffset) {
+ InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(kind, completionOffset - this.offset);
+ proposal.nameLookup = this.nameEnvironment.nameLookup;
+ proposal.completionEngine = this;
+ return proposal;
+ }
+
+ private CompletionProposal createRequiredTypeProposal(Binding binding, int start, int end, int relevance) {
+ InternalCompletionProposal proposal = null;
+ if (binding instanceof ReferenceBinding) {
+ ReferenceBinding typeBinding = (ReferenceBinding) binding;
+
+ char[] packageName = typeBinding.qualifiedPackageName();
+ char[] typeName = typeBinding.qualifiedSourceName();
+ char[] fullyQualifiedName = CharOperation.concat(packageName, typeName, '.');
+
+ proposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
+ proposal.nameLookup = this.nameEnvironment.nameLookup;
+ proposal.completionEngine = this;
+ proposal.setDeclarationSignature(packageName);
+ proposal.setSignature(getRequiredTypeSignature(typeBinding));
+ proposal.setPackageName(packageName);
+ proposal.setTypeName(typeName);
+ proposal.setCompletion(fullyQualifiedName);
+ proposal.setFlags(typeBinding.modifiers);
+ proposal.setReplaceRange(start - this.offset, end - this.offset);
+ proposal.setTokenRange(start - this.offset, end - this.offset);
+ proposal.setRelevance(relevance);
+ } else if (binding instanceof PackageBinding) {
+ PackageBinding packageBinding = (PackageBinding) binding;
+
+ char[] packageName = CharOperation.concatWith(packageBinding.compoundName, '.');
+
+ proposal = createProposal(CompletionProposal.PACKAGE_REF, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(packageName);
+ proposal.setPackageName(packageName);
+ proposal.setCompletion(packageName);
+ proposal.setReplaceRange(start - this.offset, end - this.offset);
+ proposal.setTokenRange(start - this.offset, end - this.offset);
+ proposal.setRelevance(relevance);
+ }
+ return proposal;
+ }
+
+ private void createType(TypeBinding type, Scope scope, StringBuffer completion) {
+ switch (type.kind()) {
+ case Binding.BASE_TYPE :
+ completion.append(type.sourceName());
+ break;
+ case Binding.WILDCARD_TYPE :
+ case Binding.INTERSECTION_TYPE : // TODO (david) need to handle intersection type specifically
+ WildcardBinding wildcardBinding = (WildcardBinding) type;
+ completion.append('?');
+ switch (wildcardBinding.boundKind) {
+ case Wildcard.EXTENDS:
+ completion.append(' ');
+ completion.append(EXTENDS);
+ completion.append(' ');
+ createType(wildcardBinding.bound, scope, completion);
+ if(wildcardBinding.otherBounds != null) {
+
+ int length = wildcardBinding.otherBounds.length;
+ for (int i = 0; i < length; i++) {
+ completion.append(' ');
+ completion.append('&');
+ completion.append(' ');
+ createType(wildcardBinding.otherBounds[i], scope, completion);
+ }
+ }
+ break;
+ case Wildcard.SUPER:
+ completion.append(' ');
+ completion.append(SUPER);
+ completion.append(' ');
+ createType(wildcardBinding.bound, scope, completion);
+ break;
+ }
+ break;
+ case Binding.ARRAY_TYPE :
+ createType(type.leafComponentType(), scope, completion);
+ int dim = type.dimensions();
+ for (int i = 0; i < dim; i++) {
+ completion.append('[');
+ completion.append(']');
+ }
+ break;
+ case Binding.PARAMETERIZED_TYPE :
+ ParameterizedTypeBinding parameterizedType = (ParameterizedTypeBinding) type;
+ if (type.isMemberType()) {
+ createType(parameterizedType.enclosingType(), scope, completion);
+ completion.append('.');
+ completion.append(parameterizedType.sourceName);
+ } else {
+ completion.append(CharOperation.concatWith(parameterizedType.genericType().compoundName, '.'));
+ }
+ if (parameterizedType.arguments != null) {
+ completion.append('<');
+ for (int i = 0, length = parameterizedType.arguments.length; i < length; i++) {
+ if (i != 0) completion.append(',');
+ createType(parameterizedType.arguments[i], scope, completion);
+ }
+ completion.append('>');
+ }
+ break;
+ default :
+ char[] packageName = type.qualifiedPackageName();
+ char[] typeName = type.qualifiedSourceName();
+ if(mustQualifyType(
+ (ReferenceBinding)type,
+ packageName,
+ scope)) {
+ completion.append(CharOperation.concat(packageName, typeName,'.'));
+ } else {
+ completion.append(type.sourceName());
+ }
+ break;
+ }
+ }
+
+ /*
+ * Create a completion proposal for a member type.
+ */
+ private void createTypeParameterProposal(TypeParameter typeParameter, int relevance) {
+ char[] completionName = typeParameter.name;
+
+ // Create standard type proposal
+ if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+ InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset);
+ proposal.nameLookup = this.nameEnvironment.nameLookup;
+ proposal.completionEngine = this;
+ proposal.setSignature(getSignature(typeParameter.binding));
+ proposal.setTypeName(completionName);
+ proposal.setCompletion(completionName);
+ proposal.setFlags(typeParameter.modifiers);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+
+ // Create javadoc text proposal if necessary
+ if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
+ char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
+ InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
+ proposal.nameLookup = this.nameEnvironment.nameLookup;
+ proposal.completionEngine = this;
+ proposal.setSignature(getSignature(typeParameter.binding));
+ proposal.setTypeName(javadocCompletion);
+ proposal.setCompletion(javadocCompletion);
+ proposal.setFlags(typeParameter.modifiers);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance+R_INLINE_TAG);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ }
+
+ /*
+ * Create a completion proposal for a type.
+ */
+ private void createTypeProposal(char[] packageName, char[] typeName, int modifiers, int accessibility, char[] completionName, int relevance) {
+
+ // Create standard type proposal
+ if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
+ InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset);
+ proposal.nameLookup = this.nameEnvironment.nameLookup;
+ proposal.completionEngine = this;
+ proposal.setDeclarationSignature(packageName);
+ proposal.setSignature(createNonGenericTypeSignature(packageName, typeName));
+ proposal.setPackageName(packageName);
+ proposal.setTypeName(typeName);
+ proposal.setCompletion(completionName);
+ proposal.setFlags(modifiers);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ proposal.setAccessibility(accessibility);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+
+ // Create javadoc text proposal if necessary
+ if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
+ char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
+ InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
+ proposal.nameLookup = this.nameEnvironment.nameLookup;
+ proposal.completionEngine = this;
+ proposal.setDeclarationSignature(packageName);
+ proposal.setSignature(createNonGenericTypeSignature(packageName, typeName));
+ proposal.setPackageName(packageName);
+ proposal.setTypeName(typeName);
+ proposal.setCompletion(javadocCompletion);
+ proposal.setFlags(modifiers);
+ int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
+ proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance+R_INLINE_TAG);
+ proposal.setAccessibility(accessibility);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ }
+
+ /*
+ * Create a completion proposal for a member type.
+ */
+ private void createTypeProposal(
+ ReferenceBinding refBinding,
+ char[] typeName,
+ int accessibility,
+ char[] completionName,
+ int relevance,
+ Binding[] missingElements,
+ int[] missingElementsStarts,
+ int[] missingElementsEnds,
+ boolean missingElementsHaveProblems) {
+
+ // Create standard type proposal
+ if(!this.isIgnored(CompletionProposal.TYPE_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
+ InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset);
+ proposal.nameLookup = this.nameEnvironment.nameLookup;
+ proposal.completionEngine = this;
+ proposal.setDeclarationSignature(refBinding.qualifiedPackageName());
+ proposal.setSignature(getCompletedTypeSignature(refBinding));
+ proposal.setPackageName(refBinding.qualifiedPackageName());
+ proposal.setTypeName(typeName);
+ if (missingElements != null) {
+ CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
+ for (int i = 0; i < missingElements.length; i++) {
+ subProposals[i] =
+ createRequiredTypeProposal(
+ missingElements[i],
+ missingElementsStarts[i],
+ missingElementsEnds[i],
+ relevance);
+ }
+ proposal.setRequiredProposals(subProposals);
+ }
+ proposal.setCompletion(completionName);
+ proposal.setFlags(refBinding.modifiers);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+
+ // Create javadoc text proposal if necessary
+ if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(Comp